@mineminemine/esc-pos-encoder-ionic
Advanced tools
| 'use strict'; | ||
| var linewrap = require('linewrap'); | ||
| var canvas = require('canvas'); | ||
| var Dither = require('canvas-dither'); | ||
| var Flatten = require('canvas-flatten'); | ||
| var CodepageEncoder = require('codepage-encoder'); | ||
| const codepageMappings = { | ||
| epson: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp851': 0x0b, | ||
| 'cp853': 0x0c, | ||
| 'cp857': 0x0d, | ||
| 'cp737': 0x0e, | ||
| 'iso88597': 0x0f, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| 'cp720': 0x20, | ||
| 'cp775': 0x21, | ||
| 'cp855': 0x22, | ||
| 'cp861': 0x23, | ||
| 'cp862': 0x24, | ||
| 'cp864': 0x25, | ||
| 'cp869': 0x26, | ||
| 'iso88592': 0x27, | ||
| 'iso885915': 0x28, | ||
| 'cp1098': 0x29, | ||
| 'cp1118': 0x2a, | ||
| 'cp1119': 0x2b, | ||
| 'cp1125': 0x2c, | ||
| 'windows1250': 0x2d, | ||
| 'windows1251': 0x2e, | ||
| 'windows1253': 0x2f, | ||
| 'windows1254': 0x30, | ||
| 'windows1255': 0x31, | ||
| 'windows1256': 0x32, | ||
| 'windows1257': 0x33, | ||
| 'windows1258': 0x34, | ||
| 'rk1048': 0x35, | ||
| }, | ||
| zjiang: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| 'windows1255': 0x20, | ||
| 'cp861': 0x38, | ||
| 'cp855': 0x3c, | ||
| 'cp857': 0x3d, | ||
| 'cp862': 0x3e, | ||
| 'cp864': 0x3f, | ||
| 'cp737': 0x40, | ||
| 'cp851': 0x41, | ||
| 'cp869': 0x42, | ||
| 'cp1119': 0x44, | ||
| 'cp1118': 0x45, | ||
| 'windows1250': 0x48, | ||
| 'windows1251': 0x49, | ||
| 'cp3840': 0x4a, | ||
| 'cp3843': 0x4c, | ||
| 'cp3844': 0x4d, | ||
| 'cp3845': 0x4e, | ||
| 'cp3846': 0x4f, | ||
| 'cp3847': 0x50, | ||
| 'cp3848': 0x51, | ||
| 'cp2001': 0x53, | ||
| 'cp3001': 0x54, | ||
| 'cp3002': 0x55, | ||
| 'cp3011': 0x56, | ||
| 'cp3012': 0x57, | ||
| 'cp3021': 0x58, | ||
| 'cp3041': 0x59, | ||
| 'windows1253': 0x5a, | ||
| 'windows1254': 0x5b, | ||
| 'windows1256': 0x5c, | ||
| 'cp720': 0x5d, | ||
| 'windows1258': 0x5e, | ||
| 'cp775': 0x5f, | ||
| }, | ||
| bixolon: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp851': 0x0b, | ||
| 'cp858': 0x13, | ||
| }, | ||
| star: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| }, | ||
| citizen: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp852': 0x12, | ||
| 'cp866': 0x11, | ||
| 'cp857': 0x08, | ||
| 'windows1252': 0x10, | ||
| 'cp858': 0x13, | ||
| 'cp864': 0x28, | ||
| }, | ||
| legacy: { | ||
| 'cp437': 0x00, | ||
| 'cp737': 0x40, | ||
| 'cp850': 0x02, | ||
| 'cp775': 0x5f, | ||
| 'cp852': 0x12, | ||
| 'cp855': 0x3c, | ||
| 'cp857': 0x3d, | ||
| 'cp858': 0x13, | ||
| 'cp860': 0x03, | ||
| 'cp861': 0x38, | ||
| 'cp862': 0x3e, | ||
| 'cp863': 0x04, | ||
| 'cp864': 0x1c, | ||
| 'cp865': 0x05, | ||
| 'cp866': 0x11, | ||
| 'cp869': 0x42, | ||
| 'cp936': 0xff, | ||
| 'cp949': 0xfd, | ||
| 'cp950': 0xfe, | ||
| 'cp1252': 0x10, | ||
| 'iso88596': 0x16, | ||
| 'shiftjis': 0xfc, | ||
| 'windows874': 0x1e, | ||
| 'windows1250': 0x48, | ||
| 'windows1251': 0x49, | ||
| 'windows1252': 0x47, | ||
| 'windows1253': 0x5a, | ||
| 'windows1254': 0x5b, | ||
| 'windows1255': 0x20, | ||
| 'windows1256': 0x5c, | ||
| 'windows1257': 0x19, | ||
| 'windows1258': 0x5e, | ||
| }, | ||
| }; | ||
| /** | ||
| * Create a byte stream based on commands for ESC/POS printers | ||
| */ | ||
| class EscPosEncoder { | ||
| /** | ||
| * Create a new object | ||
| * | ||
| * @param {object} options Object containing configuration options | ||
| */ | ||
| constructor(options) { | ||
| this._reset(options); | ||
| } | ||
| /** | ||
| * Reset the state of the object | ||
| * | ||
| * @param {object} options Object containing configuration options | ||
| */ | ||
| _reset(options) { | ||
| this._options = Object.assign({ | ||
| width: null, | ||
| embedded: false, | ||
| wordWrap: true, | ||
| imageMode: 'column', | ||
| codepageMapping: 'epson', | ||
| codepageCandidates: [ | ||
| 'cp437', 'cp858', 'cp860', 'cp861', 'cp863', 'cp865', | ||
| 'cp852', 'cp857', 'cp855', 'cp866', 'cp869', | ||
| ], | ||
| }, options); | ||
| this._embedded = this._options.width && this._options.embedded; | ||
| this._buffer = []; | ||
| this._queued = []; | ||
| this._cursor = 0; | ||
| this._codepage = 'ascii'; | ||
| this._state = { | ||
| 'codepage': 0, | ||
| 'align': 'left', | ||
| 'bold': false, | ||
| 'italic': false, | ||
| 'underline': false, | ||
| 'invert': false, | ||
| 'width': 1, | ||
| 'height': 1, | ||
| }; | ||
| } | ||
| /** | ||
| * Encode a string with the current code page | ||
| * | ||
| * @param {string} value String to encode | ||
| * @return {object} Encoded string as a ArrayBuffer | ||
| * | ||
| */ | ||
| _encode(value) { | ||
| if (this._codepage != 'auto') { | ||
| return CodepageEncoder.encode(value, this._codepage); | ||
| } | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| const fragments = CodepageEncoder.autoEncode(value, this._options.codepageCandidates); | ||
| let length = 0; | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| length += 3 + fragments[f].bytes.byteLength; | ||
| } | ||
| const buffer = new Uint8Array(length); | ||
| let i = 0; | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| buffer.set([0x1b, 0x74, codepages[fragments[f].codepage]], i); | ||
| buffer.set(fragments[f].bytes, i + 3); | ||
| i += 3 + fragments[f].bytes.byteLength; | ||
| this._state.codepage = codepages[fragments[f].codepage]; | ||
| } | ||
| return buffer; | ||
| } | ||
| /** | ||
| * Add commands to the queue | ||
| * | ||
| * @param {array} value Add array of numbers, arrays, buffers or Uint8Arrays to add to the buffer | ||
| * | ||
| */ | ||
| _queue(value) { | ||
| value.forEach((item) => this._queued.push(item)); | ||
| } | ||
| /** | ||
| * Flush current queue to the buffer | ||
| * | ||
| */ | ||
| _flush() { | ||
| if (this._embedded) { | ||
| let indent = this._options.width - this._cursor; | ||
| if (this._state.align == 'left') { | ||
| this._queued.push((new Array(indent)).fill(0x20)); | ||
| } | ||
| if (this._state.align == 'center') { | ||
| const remainder = indent % 2; | ||
| indent = indent >> 1; | ||
| if (indent > 0) { | ||
| this._queued.push((new Array(indent)).fill(0x20)); | ||
| } | ||
| if (indent + remainder > 0) { | ||
| this._queued.unshift((new Array(indent + remainder)).fill(0x20)); | ||
| } | ||
| } | ||
| if (this._state.align == 'right') { | ||
| this._queued.unshift((new Array(indent)).fill(0x20)); | ||
| } | ||
| } | ||
| this._buffer = this._buffer.concat(this._queued); | ||
| this._queued = []; | ||
| this._cursor = 0; | ||
| } | ||
| /** | ||
| * Wrap the text while respecting the position of the cursor | ||
| * | ||
| * @param {string} value String to wrap after the width of the paper has been reached | ||
| * @param {number} position Position on which to force a wrap | ||
| * @return {array} Array with each line | ||
| */ | ||
| _wrap(value, position) { | ||
| if (position || (this._options.wordWrap && this._options.width)) { | ||
| const indent = '-'.repeat(this._cursor); | ||
| const w = linewrap(position || this._options.width, {lineBreak: '\n', whitespace: 'all'}); | ||
| const result = w(indent + value).substring(this._cursor).split('\n'); | ||
| return result; | ||
| } | ||
| return [value]; | ||
| } | ||
| /** | ||
| * Restore styles and codepages after drawing boxes or lines | ||
| */ | ||
| _restoreState() { | ||
| this.bold(this._state.bold); | ||
| this.italic(this._state.italic); | ||
| this.underline(this._state.underline); | ||
| this.invert(this._state.invert); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._state.codepage, | ||
| ]); | ||
| } | ||
| /** | ||
| * Get code page identifier for the specified code page and mapping | ||
| * | ||
| * @param {string} codepage Required code page | ||
| * @return {number} Identifier for the current printer according to the specified mapping | ||
| */ | ||
| _getCodepageIdentifier(codepage) { | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| return codepages[codepage]; | ||
| } | ||
| /** | ||
| * Initialize the printer | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| initialize() { | ||
| this._queue([ | ||
| 0x1b, 0x40, | ||
| ]); | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change the code page | ||
| * | ||
| * @param {string} codepage The codepage that we set the printer to | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| codepage(codepage) { | ||
| if (codepage === 'auto') { | ||
| this._codepage = codepage; | ||
| return this; | ||
| } | ||
| if (!CodepageEncoder.supports(codepage)) { | ||
| throw new Error('Unknown codepage'); | ||
| } | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| if (typeof codepages[codepage] !== 'undefined') { | ||
| this._codepage = codepage; | ||
| this._state.codepage = codepages[codepage]; | ||
| this._queue([ | ||
| 0x1b, 0x74, codepages[codepage], | ||
| ]); | ||
| } else { | ||
| throw new Error('Codepage not supported by printer'); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print text | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| text(value, wrap) { | ||
| const lines = this._wrap(value, wrap); | ||
| for (let l = 0; l < lines.length; l++) { | ||
| const bytes = this._encode(lines[l]); | ||
| this._queue([ | ||
| bytes, | ||
| ]); | ||
| this._cursor += (lines[l].length * this._state.width); | ||
| if (this._options.width && !this._embedded) { | ||
| this._cursor = this._cursor % this._options.width; | ||
| } | ||
| if (l < lines.length - 1) { | ||
| this.newline(); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print a newline | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| newline() { | ||
| this._flush(); | ||
| this._queue([ | ||
| 0x0a, 0x0d, | ||
| ]); | ||
| if (this._embedded) { | ||
| this._restoreState(); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print text, followed by a newline | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| line(value, wrap) { | ||
| this.text(value, wrap); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Underline text | ||
| * | ||
| * @param {boolean|number} value true to turn on underline, false to turn off, or 2 for double underline | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| underline(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.underline; | ||
| } | ||
| this._state.underline = value; | ||
| this._queue([ | ||
| 0x1b, 0x2d, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Italic text | ||
| * | ||
| * @param {boolean} value true to turn on italic, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| italic(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.italic; | ||
| } | ||
| this._state.italic = value; | ||
| this._queue([ | ||
| 0x1b, 0x34, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Bold text | ||
| * | ||
| * @param {boolean} value true to turn on bold, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| bold(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.bold; | ||
| } | ||
| this._state.bold = value; | ||
| this._queue([ | ||
| 0x1b, 0x45, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change width of text | ||
| * | ||
| * @param {number} width The width of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| width(width) { | ||
| if (typeof width === 'undefined') { | ||
| width = 1; | ||
| } | ||
| if (typeof width !== 'number') { | ||
| throw new Error('Width must be a number'); | ||
| } | ||
| if (width < 1 || width > 8) { | ||
| throw new Error('Width must be between 1 and 8'); | ||
| } | ||
| this._state.width = width; | ||
| this._queue([ | ||
| 0x1d, 0x21, (this._state.height - 1) | (this._state.width - 1) << 4, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change height of text | ||
| * | ||
| * @param {number} height The height of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| height(height) { | ||
| if (typeof height === 'undefined') { | ||
| height = 1; | ||
| } | ||
| if (typeof height !== 'number') { | ||
| throw new Error('Height must be a number'); | ||
| } | ||
| if (height < 1 || height > 8) { | ||
| throw new Error('Height must be between 1 and 8'); | ||
| } | ||
| this._state.height = height; | ||
| this._queue([ | ||
| 0x1d, 0x21, (this._state.height - 1) | (this._state.width - 1) << 4, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Invert text | ||
| * | ||
| * @param {boolean} value true to turn on white text on black, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| invert(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.invert; | ||
| } | ||
| this._state.invert = value; | ||
| this._queue([ | ||
| 0x1d, 0x42, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change text size | ||
| * | ||
| * @param {string} value small or normal | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| size(value) { | ||
| if (value === 'small') { | ||
| value = 0x01; | ||
| } else { | ||
| value = 0x00; | ||
| } | ||
| this._queue([ | ||
| 0x1b, 0x4d, value, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change text alignment | ||
| * | ||
| * @param {string} value left, center or right | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| align(value) { | ||
| const alignments = { | ||
| 'left': 0x00, | ||
| 'center': 0x01, | ||
| 'right': 0x02, | ||
| }; | ||
| if (value in alignments) { | ||
| this._state.align = value; | ||
| if (!this._embedded) { | ||
| this._queue([ | ||
| 0x1b, 0x61, alignments[value], | ||
| ]); | ||
| } | ||
| } else { | ||
| throw new Error('Unknown alignment'); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a table | ||
| * | ||
| * @param {array} columns The column definitions | ||
| * @param {array} data Array containing rows. Each row is an array containing cells. | ||
| * Each cell can be a string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| table(columns, data) { | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| for (let r = 0; r < data.length; r++) { | ||
| const lines = []; | ||
| let maxLines = 0; | ||
| for (let c = 0; c < columns.length; c++) { | ||
| const cell = []; | ||
| if (typeof data[r][c] === 'string') { | ||
| const w = linewrap(columns[c].width, {lineBreak: '\n'}); | ||
| const fragments = w(data[r][c]).split('\n'); | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| if (columns[c].align == 'right') { | ||
| cell[f] = this._encode(fragments[f].padStart(columns[c].width)); | ||
| } else { | ||
| cell[f] = this._encode(fragments[f].padEnd(columns[c].width)); | ||
| } | ||
| } | ||
| } | ||
| if (typeof data[r][c] === 'function') { | ||
| const columnEncoder = new EscPosEncoder(Object.assign({}, this._options, { | ||
| width: columns[c].width, | ||
| embedded: true, | ||
| })); | ||
| columnEncoder._codepage = this._codepage; | ||
| columnEncoder.align(columns[c].align); | ||
| data[r][c](columnEncoder); | ||
| const encoded = columnEncoder.encode(); | ||
| let fragment = []; | ||
| for (let e = 0; e < encoded.byteLength; e++) { | ||
| if (e < encoded.byteLength - 1) { | ||
| if (encoded[e] === 0x0a && encoded[e + 1] === 0x0d) { | ||
| cell.push(fragment); | ||
| fragment = []; | ||
| e++; | ||
| continue; | ||
| } | ||
| } | ||
| fragment.push(encoded[e]); | ||
| } | ||
| if (fragment.length) { | ||
| cell.push(fragment); | ||
| } | ||
| } | ||
| maxLines = Math.max(maxLines, cell.length); | ||
| lines[c] = cell; | ||
| } | ||
| for (let c = 0; c < columns.length; c++) { | ||
| if (lines[c].length < maxLines) { | ||
| for (let p = lines[c].length; p < maxLines; p++) { | ||
| let verticalAlign = 'top'; | ||
| if (typeof columns[c].verticalAlign !== 'undefined') { | ||
| verticalAlign = columns[c].verticalAlign; | ||
| } | ||
| if (verticalAlign == 'bottom') { | ||
| lines[c].unshift((new Array(columns[c].width)).fill(0x20)); | ||
| } else { | ||
| lines[c].push((new Array(columns[c].width)).fill(0x20)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| for (let l = 0; l < maxLines; l++) { | ||
| for (let c = 0; c < columns.length; c++) { | ||
| if (typeof columns[c].marginLeft !== 'undefined') { | ||
| this.raw((new Array(columns[c].marginLeft)).fill(0x20)); | ||
| } | ||
| this.raw(lines[c][l]); | ||
| if (typeof columns[c].marginRight !== 'undefined') { | ||
| this.raw((new Array(columns[c].marginRight)).fill(0x20)); | ||
| } | ||
| } | ||
| this.newline(); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a horizontal rule | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the line, either single or double | ||
| * - width: The width of the line, by default the width of the paper | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| rule(options) { | ||
| options = Object.assign({ | ||
| style: 'single', | ||
| width: this._options.width || 10, | ||
| }, options || {}); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| (new Array(options.width)).fill(options.style === 'double' ? 0xcd : 0xc4), | ||
| ]); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._state.codepage, | ||
| ]); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a box | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the border, either single or double | ||
| * - width: The width of the box, by default the width of the paper | ||
| * - marginLeft: Space between the left border and the left edge | ||
| * - marginRight: Space between the right border and the right edge | ||
| * - paddingLeft: Space between the contents and the left border of the box | ||
| * - paddingRight: Space between the contents and the right border of the box | ||
| * @param {string|function} contents A string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| box(options, contents) { | ||
| options = Object.assign({ | ||
| style: 'single', | ||
| width: this._options.width || 30, | ||
| marginLeft: 0, | ||
| marginRight: 0, | ||
| paddingLeft: 0, | ||
| paddingRight: 0, | ||
| }, options || {}); | ||
| let elements; | ||
| if (options.style == 'double') { | ||
| elements = [0xc9, 0xbb, 0xc8, 0xbc, 0xcd, 0xba]; // ╔╗╚╝═║ | ||
| } else { | ||
| elements = [0xda, 0xbf, 0xc0, 0xd9, 0xc4, 0xb3]; // ┌┐└┘─│ | ||
| } | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| this._restoreState(); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| ]); | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[0], | ||
| new Array(options.width - 2).fill(elements[4]), | ||
| elements[1], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this.newline(); | ||
| const cell = []; | ||
| if (typeof contents === 'string') { | ||
| const w = linewrap(options.width - 2 - options.paddingLeft - options.paddingRight, {lineBreak: '\n'}); | ||
| const fragments = w(contents).split('\n'); | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| if (options.align == 'right') { | ||
| cell[f] = this._encode(fragments[f].padStart(options.width - 2 - options.paddingLeft - options.paddingRight)); | ||
| } else { | ||
| cell[f] = this._encode(fragments[f].padEnd(options.width - 2 - options.paddingLeft - options.paddingRight)); | ||
| } | ||
| } | ||
| } | ||
| if (typeof contents === 'function') { | ||
| const columnEncoder = new EscPosEncoder(Object.assign({}, this._options, { | ||
| width: options.width - 2 - options.paddingLeft - options.paddingRight, | ||
| embedded: true, | ||
| })); | ||
| columnEncoder._codepage = this._codepage; | ||
| columnEncoder.align(options.align); | ||
| contents(columnEncoder); | ||
| const encoded = columnEncoder.encode(); | ||
| let fragment = []; | ||
| for (let e = 0; e < encoded.byteLength; e++) { | ||
| if (e < encoded.byteLength - 1) { | ||
| if (encoded[e] === 0x0a && encoded[e + 1] === 0x0d) { | ||
| cell.push(fragment); | ||
| fragment = []; | ||
| e++; | ||
| continue; | ||
| } | ||
| } | ||
| fragment.push(encoded[e]); | ||
| } | ||
| if (fragment.length) { | ||
| cell.push(fragment); | ||
| } | ||
| } | ||
| for (let c = 0; c < cell.length; c++) { | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[5], | ||
| new Array(options.paddingLeft).fill(0x20), | ||
| ]); | ||
| this._queue([ | ||
| cell[c], | ||
| ]); | ||
| this._restoreState(); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| ]); | ||
| this._queue([ | ||
| new Array(options.paddingRight).fill(0x20), | ||
| elements[5], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this.newline(); | ||
| } | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[2], | ||
| new Array(options.width - 2).fill(elements[4]), | ||
| elements[3], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this._restoreState(); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Barcode | ||
| * | ||
| * @param {string} value the value of the barcode | ||
| * @param {string} symbology the type of the barcode | ||
| * @param {number} height height of the barcode | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| barcode(value, symbology, height) { | ||
| if (this._embedded) { | ||
| throw new Error('Barcodes are not supported in table cells or boxes'); | ||
| } | ||
| const symbologies = { | ||
| 'upca': 0x00, | ||
| 'upce': 0x01, | ||
| 'ean13': 0x02, | ||
| 'ean8': 0x03, | ||
| 'code39': 0x04, | ||
| 'coda39': 0x04, /* typo, leave here for backwards compatibility */ | ||
| 'itf': 0x05, | ||
| 'codabar': 0x06, | ||
| 'code93': 0x48, | ||
| 'code128': 0x49, | ||
| 'gs1-128': 0x50, | ||
| 'gs1-databar-omni': 0x51, | ||
| 'gs1-databar-truncated': 0x52, | ||
| 'gs1-databar-limited': 0x53, | ||
| 'gs1-databar-expanded': 0x54, | ||
| 'code128-auto': 0x55, | ||
| }; | ||
| if (symbology in symbologies) { | ||
| const bytes = CodepageEncoder.encode(value, 'ascii'); | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x68, height, | ||
| 0x1d, 0x77, symbology === 'code39' ? 0x02 : 0x03, | ||
| ]); | ||
| if (symbology == 'code128' && bytes[0] !== 0x7b) { | ||
| /* Not yet encodeded Code 128, assume data is Code B, which is similar to ASCII without control chars */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes.length + 2, | ||
| 0x7b, 0x42, | ||
| bytes, | ||
| ]); | ||
| } else if (symbologies[symbology] > 0x40) { | ||
| /* Function B symbologies */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes.length, | ||
| bytes, | ||
| ]); | ||
| } else { | ||
| /* Function A symbologies */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes, | ||
| 0x00, | ||
| ]); | ||
| } | ||
| } else { | ||
| throw new Error('Symbology not supported by printer'); | ||
| } | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * QR code | ||
| * | ||
| * @param {string} value the value of the qr code | ||
| * @param {number} model model of the qrcode, either 1 or 2 | ||
| * @param {number} size size of the qrcode, a value between 1 and 8 | ||
| * @param {string} errorlevel the amount of error correction used, either 'l', 'm', 'q', 'h' | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| qrcode(value, model, size, errorlevel) { | ||
| if (this._embedded) { | ||
| throw new Error('QR codes are not supported in table cells or boxes'); | ||
| } | ||
| /* Force printing the print buffer and moving to a new line */ | ||
| this._queue([ | ||
| 0x0a, | ||
| ]); | ||
| /* Model */ | ||
| const models = { | ||
| 1: 0x31, | ||
| 2: 0x32, | ||
| }; | ||
| if (typeof model === 'undefined') { | ||
| model = 2; | ||
| } | ||
| if (model in models) { | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x04, 0x00, 0x31, 0x41, models[model], 0x00, | ||
| ]); | ||
| } else { | ||
| throw new Error('Model must be 1 or 2'); | ||
| } | ||
| /* Size */ | ||
| if (typeof size === 'undefined') { | ||
| size = 6; | ||
| } | ||
| if (typeof size !== 'number') { | ||
| throw new Error('Size must be a number'); | ||
| } | ||
| if (size < 1 || size > 8) { | ||
| throw new Error('Size must be between 1 and 8'); | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, size, | ||
| ]); | ||
| /* Error level */ | ||
| const errorlevels = { | ||
| 'l': 0x30, | ||
| 'm': 0x31, | ||
| 'q': 0x32, | ||
| 'h': 0x33, | ||
| }; | ||
| if (typeof errorlevel === 'undefined') { | ||
| errorlevel = 'm'; | ||
| } | ||
| if (errorlevel in errorlevels) { | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x45, errorlevels[errorlevel], | ||
| ]); | ||
| } else { | ||
| throw new Error('Error level must be l, m, q or h'); | ||
| } | ||
| /* Data */ | ||
| const bytes = CodepageEncoder.encode(value, 'iso88591'); | ||
| const length = bytes.length + 3; | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, length % 0xff, length / 0xff, 0x31, 0x50, 0x30, bytes, | ||
| ]); | ||
| /* Print QR code */ | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30, | ||
| ]); | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Image | ||
| * | ||
| * @param {object} element an element, like a canvas or image that needs to be printed | ||
| * @param {number} width width of the image on the printer | ||
| * @param {number} height height of the image on the printer | ||
| * @param {string} algorithm the dithering algorithm for making the image black and white | ||
| * @param {number} threshold threshold for the dithering algorithm | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| image(element, width, height, algorithm, threshold) { | ||
| if (this._embedded) { | ||
| throw new Error('Images are not supported in table cells or boxes'); | ||
| } | ||
| if (width % 8 !== 0) { | ||
| throw new Error('Width must be a multiple of 8'); | ||
| } | ||
| if (height % 8 !== 0) { | ||
| throw new Error('Height must be a multiple of 8'); | ||
| } | ||
| if (typeof algorithm === 'undefined') { | ||
| algorithm = 'threshold'; | ||
| } | ||
| if (typeof threshold === 'undefined') { | ||
| threshold = 128; | ||
| } | ||
| const canvas$1 = canvas.createCanvas(width, height); | ||
| const context = canvas$1.getContext('2d'); | ||
| context.drawImage(element, 0, 0, width, height); | ||
| let image = context.getImageData(0, 0, width, height); | ||
| image = Flatten.flatten(image, [0xff, 0xff, 0xff]); | ||
| switch (algorithm) { | ||
| case 'threshold': image = Dither.threshold(image, threshold); break; | ||
| case 'bayer': image = Dither.bayer(image, threshold); break; | ||
| case 'floydsteinberg': image = Dither.floydsteinberg(image); break; | ||
| case 'atkinson': image = Dither.atkinson(image); break; | ||
| } | ||
| const getPixel = (x, y) => x < width && y < height ? (image.data[((width * y) + x) * 4] > 0 ? 0 : 1) : 0; | ||
| const getColumnData = (width, height) => { | ||
| const data = []; | ||
| for (let s = 0; s < Math.ceil(height / 24); s++) { | ||
| const bytes = new Uint8Array(width * 3); | ||
| for (let x = 0; x < width; x++) { | ||
| for (let c = 0; c < 3; c++) { | ||
| for (let b = 0; b < 8; b++) { | ||
| bytes[(x * 3) + c] |= getPixel(x, (s * 24) + b + (8 * c)) << (7 - b); | ||
| } | ||
| } | ||
| } | ||
| data.push(bytes); | ||
| } | ||
| return data; | ||
| }; | ||
| const getRowData = (width, height) => { | ||
| const bytes = new Uint8Array((width * height) >> 3); | ||
| for (let y = 0; y < height; y++) { | ||
| for (let x = 0; x < width; x = x + 8) { | ||
| for (let b = 0; b < 8; b++) { | ||
| bytes[(y * (width >> 3)) + (x >> 3)] |= getPixel(x + b, y) << (7 - b); | ||
| } | ||
| } | ||
| } | ||
| return bytes; | ||
| }; | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| /* Encode images with ESC * */ | ||
| if (this._options.imageMode == 'column') { | ||
| this._queue([ | ||
| 0x1b, 0x33, 0x24, | ||
| ]); | ||
| getColumnData(width, height).forEach((bytes) => { | ||
| this._queue([ | ||
| 0x1b, 0x2a, 0x21, | ||
| (width) & 0xff, (((width) >> 8) & 0xff), | ||
| bytes, | ||
| 0x0a, | ||
| ]); | ||
| }); | ||
| this._queue([ | ||
| 0x1b, 0x32, | ||
| ]); | ||
| } | ||
| /* Encode images with GS v */ | ||
| if (this._options.imageMode == 'raster') { | ||
| this._queue([ | ||
| 0x1d, 0x76, 0x30, 0x00, | ||
| (width >> 3) & 0xff, (((width >> 3) >> 8) & 0xff), | ||
| height & 0xff, ((height >> 8) & 0xff), | ||
| getRowData(width, height), | ||
| ]); | ||
| } | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Cut paper | ||
| * | ||
| * @param {string} value full or partial. When not specified a full cut will be assumed | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| cut(value) { | ||
| if (this._embedded) { | ||
| throw new Error('Cut is not supported in table cells or boxes'); | ||
| } | ||
| let data = 0x00; | ||
| if (value == 'partial') { | ||
| data = 0x01; | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x56, data, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Pulse | ||
| * | ||
| * @param {number} device 0 or 1 for on which pin the device is connected, default of 0 | ||
| * @param {number} on Time the pulse is on in milliseconds, default of 100 | ||
| * @param {number} off Time the pulse is off in milliseconds, default of 500 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| pulse(device, on, off) { | ||
| if (this._embedded) { | ||
| throw new Error('Pulse is not supported in table cells or boxes'); | ||
| } | ||
| if (typeof device === 'undefined') { | ||
| device = 0; | ||
| } | ||
| if (typeof on === 'undefined') { | ||
| on = 100; | ||
| } | ||
| if (typeof off === 'undefined') { | ||
| off = 500; | ||
| } | ||
| on = Math.min(500, Math.round(on / 2)); | ||
| off = Math.min(500, Math.round(off / 2)); | ||
| this._queue([ | ||
| 0x1b, 0x70, device ? 1 : 0, on & 0xff, off & 0xff, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Add raw printer commands | ||
| * | ||
| * @param {array} data raw bytes to be included | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| raw(data) { | ||
| this._queue(data); | ||
| return this; | ||
| } | ||
| /** | ||
| * Encode all previous commands | ||
| * | ||
| * @return {Uint8Array} Return the encoded bytes | ||
| * | ||
| */ | ||
| encode() { | ||
| this._flush(); | ||
| let length = 0; | ||
| this._buffer.forEach((item) => { | ||
| if (typeof item === 'number') { | ||
| length++; | ||
| } else { | ||
| length += item.length; | ||
| } | ||
| }); | ||
| const result = new Uint8Array(length); | ||
| let index = 0; | ||
| this._buffer.forEach((item) => { | ||
| if (typeof item === 'number') { | ||
| result[index] = item; | ||
| index++; | ||
| } else { | ||
| result.set(item, index); | ||
| index += item.length; | ||
| } | ||
| }); | ||
| this._reset(); | ||
| return result; | ||
| } | ||
| } | ||
| module.exports = EscPosEncoder; |
| function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t={exports:{}},s={html:{skipScheme:"html",lineBreakScheme:"html",whitespace:"collapse"}},i=/<\s*br(?:[\s/]*|\s[^>]*)>/gi,n={unix:[/\n/g,"\n"],dos:[/\r\n/g,"\r\n"],mac:[/\r/g,"\r"],html:[i,"<br>"],xhtml:[i,"<br/>"]},a={"ansi-color":/\x1B\[[^m]*m/g,html:/<[^>]*>/g,bbcode:/\[[^]]*\]/g},r={soft:1,hard:1},o={collapse:1,default:1,line:1,all:1},h={all:1,multi:1,none:1},l=/([sm])(\d+)/,c=/[-/\\^$*+?.()|[\]{}]/g;function p(e){return e.replace(c,"\\$&")}var d=t.exports=function(e,t,i){"object"==typeof e&&(e=(i=e).start,t=i.stop),"object"==typeof t&&(i=t,e=e||i.start,t=void 0),t||(t=e,e=0),i||(i={});var c,d,g,u,f,w,m,b,_,y,v,k,E,x,L,q,j,A,I="soft",B="default",M=4,R="all",S="",T="";if(c=i.preset)for(c instanceof Array||(c=[c]),A=0;A<c.length;A++){if(!(q=s[c[A]]))throw new TypeError('preset must be one of "'+Object.keys(s).join('", "')+'"');q.mode&&(I=q.mode),q.whitespace&&(B=q.whitespace),void 0!==q.tabWidth&&(M=q.tabWidth),q.skip&&(d=q.skip),q.skipScheme&&(g=q.skipScheme),q.lineBreak&&(u=q.lineBreak),q.lineBreakScheme&&(f=q.lineBreakScheme),q.respectLineBreaks&&(R=q.respectLineBreaks),void 0!==q.preservedLineIndent&&(m=q.preservedLineIndent),void 0!==q.wrapLineIndent&&(b=q.wrapLineIndent),q.wrapLineIndentBase&&(_=q.wrapLineIndentBase)}if(i.mode){if(!r[i.mode])throw new TypeError('mode must be one of "'+Object.keys(r).join('", "')+'"');I=i.mode}if(i.whitespace){if(!o[i.whitespace])throw new TypeError('whitespace must be one of "'+Object.keys(o).join('", "')+'"');B=i.whitespace}if(void 0!==i.tabWidth){if(!(parseInt(i.tabWidth,10)>=0))throw new TypeError("tabWidth must be a non-negative integer");M=parseInt(i.tabWidth,10)}if(L=new Array(M+1).join(" "),i.respectLineBreaks){if(!h[i.respectLineBreaks]&&!l.test(i.respectLineBreaks))throw new TypeError('respectLineBreaks must be one of "'+Object.keys(h).join('", "')+'", "m<num>", "s<num>"');R=i.respectLineBreaks}if("multi"===R)R="m",w=2;else if(!h[R]){var z=l.exec(R);R=z[1],w=parseInt(z[2],10)}if(void 0!==i.preservedLineIndent){if(!(parseInt(i.preservedLineIndent,10)>=0))throw new TypeError("preservedLineIndent must be a non-negative integer");m=parseInt(i.preservedLineIndent,10)}if(m>0&&(S=new Array(m+1).join(" ")),void 0!==i.wrapLineIndent){if(isNaN(parseInt(i.wrapLineIndent,10)))throw new TypeError("wrapLineIndent must be an integer");b=parseInt(i.wrapLineIndent,10)}if(i.wrapLineIndentBase&&(_=i.wrapLineIndentBase),_){if(void 0===b)throw new TypeError("wrapLineIndent must be specified when wrapLineIndentBase is specified");if(_ instanceof RegExp)x=_;else{if("string"!=typeof _)throw new TypeError("wrapLineIndentBase must be either a RegExp object or a string");x=new RegExp(p(_))}}else if(b>0)T=new Array(b+1).join(" ");else if(b<0)throw new TypeError("wrapLineIndent must be non-negative when a base is not specified");if(i.skipScheme){if(!a[i.skipScheme])throw new TypeError('skipScheme must be one of "'+Object.keys(a).join('", "')+'"');g=i.skipScheme}if(i.skip&&(d=i.skip),d)if(d instanceof RegExp)(y=d).global||(j="g",y.ignoreCase&&(j+="i"),y.multiline&&(j+="m"),y=new RegExp(y.source,j));else{if("string"!=typeof d)throw new TypeError("skip must be either a RegExp object or a string");y=new RegExp(p(d),"g")}if(!y&&g&&(y=a[g]),i.lineBreakScheme){if(!n[i.lineBreakScheme])throw new TypeError('lineBreakScheme must be one of "'+Object.keys(n).join('", "')+'"');f=i.lineBreakScheme}if(i.lineBreak&&(u=i.lineBreak),f&&(q=n[f])&&(v=q[0],k=q[1]),u)if(u instanceof Array&&(1===u.length?u=u[0]:u.length>=2&&(u[0]instanceof RegExp?(v=u[0],"string"==typeof u[1]&&(k=u[1])):u[1]instanceof RegExp?(v=u[1],"string"==typeof u[0]&&(k=u[0])):"string"==typeof u[0]&&"string"==typeof u[1]?(v=new RegExp(p(u[0]),"g"),k=u[1]):u=u[0])),"string"==typeof u)k=u,v||(v=new RegExp(p(u),"g"));else if(u instanceof RegExp)v=u;else if(!(u instanceof Array))throw new TypeError("lineBreak must be a RegExp object, a string, or an array consisted of a RegExp object and a string");v||(v=/\n/g,k="\n"),j="g",v.ignoreCase&&(j+="i"),v.multiline&&(j+="m"),E=new RegExp("\\s*(?:"+v.source+")(?:"+v.source+"|\\s)*",j),v.global||(v=new RegExp(v.source,j));var O="hard"===I?/\b/:/(\S+\s+)/,C=new Array(e+1).join(" "),U="default"===B||"collapse"===B,W="collapse"===B,N="line"===B,P="all"===B,G=/\t/g,H=/ +/g,K=/^\s+/,$=/\s+$/,F=/\S/,Q=/\s/,D=t-e;return function(s){var i;if(s=s.toString().replace(G,L),!k){if(v.lastIndex=0,!(i=v.exec(s)))throw new TypeError("Line break string for the output not specified");k=i[0]}var n,a,r,o,h,l,c,p,d,g=0;for(n=[],E.lastIndex=0,i=E.exec(s);i;){if(n.push(s.substring(g,i.index)),"none"!==R){for(r=[],o=0,v.lastIndex=0,a=v.exec(i[0]);a;)r.push(i[0].substring(o,a.index)),o=a.index+a[0].length,a=v.exec(i[0]);r.push(i[0].substring(o)),n.push({type:"break",breaks:r})}else h=W?" ":i[0].replace(v,""),n.push({type:"break",remaining:h});g=i.index+i[0].length,i=E.exec(s)}if(n.push(s.substring(g)),y)for(d=[],l=0;l<n.length;l++){var u=n[l];if("string"!=typeof u)d.push(u);else{for(g=0,y.lastIndex=0,i=y.exec(u);i;)d.push(u.substring(g,i.index)),d.push({type:"skip",value:i[0]}),g=i.index+i[0].length,i=y.exec(u);d.push(u.substring(g))}}else d=n;var f=[];for(l=0;l<d.length;l++){var m=d[l];if("string"!=typeof m)f.push(m);else{W&&(m=m.replace(H," "));var _=m.split(O),q=[];for(c=0;c<_.length;c++){var j=_[c];if("hard"===I)for(p=0;p<j.length;p+=D)q.push(j.slice(p,p+D));else q.push(j)}f=f.concat(q)}}var A,B=0,M=e+S.length,z=[C+S],V=0,J=!0,X=!0,Y=T;function Z(s){var i,n,a,r=z[B];if(P)M>t&&(V=V||t,a=r.length-(M-V),z[B]=r.substring(0,a)),V=0;else{for(i=r.length-1;i>=e&&" "===r[i];)i--;for(;i>=e&&Q.test(r[i]);)i--;++i!==r.length&&(z[B]=r.substring(0,i)),X&&J&&N&&M>t&&(a=r.length-(M-t))<i&&(a=i)}if(X&&(X=!1,x&&(i=z[B].substring(e).search(x),Y=i>=0&&i+b>0?new Array(i+b+1).join(" "):"")),a){for(;a+D<r.length;)P?(n=r.substring(a,a+D),z.push(C+Y+n)):z.push(C+Y),a+=D,B++;if(!s)return n=r.substring(a),Y+n;P?(n=r.substring(a),z.push(C+Y+n)):z.push(C+Y),B++}return""}for(l=0;l<f.length;l++){var ee=f[l];if(""!==ee)if("string"==typeof ee){for(var te;;){if(te=void 0,M+ee.length>t&&M+(te=ee.replace($,"")).length>t&&""!==te&&M>e){if(A=Z(!1),z.push(C+Y),B++,M=e+Y.length,A){z[B]+=A,M+=A.length,J=!0;continue}!U&&(!N||X&&J)||(ee=ee.replace(K,"")),J=!1}else J&&(U||N&&(!X||!J)?""!==(ee=ee.replace(K,""))&&(J=!1):F.test(ee)&&(J=!1));break}P&&te&&M+te.length>t&&(V=M+te.length),z[B]+=ee,M+=ee.length}else if("break"===ee.type)if("none"!==R){var se=ee.breaks,ie=se.length-1;if("s"===R){for(c=0;c<ie;c++)se[c+1].length<w?se[c+1]=W?" ":se[c]+se[c+1]:(P&&(z[B]+=se[c],M+=se[c].length),Z(!0),z.push(C+S),B++,M=e+S.length,X=J=!0);(!J||P||N&&X)&&((W||!J&&""===se[ie])&&(se[ie]=" "),z[B]+=se[ie],M+=se[ie].length)}else if("m"===R&&ie<w)(!J||P||N&&X)&&(W?ee=" ":(ee=se.join(""),J||""!==ee||(ee=" ")),z[B]+=ee,M+=ee.length);else if(U){for(Z(!0),c=0;c<ie;c++)z.push(C+S),B++;M=e+S.length,X=J=!0}else for((P||X&&J)&&(z[B]+=se[0],M+=se[0].length),c=0;c<ie;c++)Z(!0),z.push(C+S+se[c+1]),B++,M=e+S.length+se[c+1].length,X=J=!0}else(!J||P||N&&X)&&(ee=ee.remaining,(W||!J&&""===ee)&&(ee=" "),z[B]+=ee,M+=ee.length);else"skip"===ee.type&&(M>t&&(A=Z(!1),z.push(C+Y),B++,M=e+Y.length,A&&(z[B]+=A,M+=A.length),J=!0),z[B]+=ee.value)}return Z(!0),z.join(k)}};d.soft=d,d.hard=function(){var e=[].slice.call(arguments),t=e.length-1;return"object"==typeof e[t]?e[t].mode="hard":e.push({mode:"hard"}),d.apply(null,e)},d.wrap=function(e){var t=[].slice.call(arguments);return t.shift(),d.apply(null,t)(e)};var g=e(t.exports);var u=e(new class{grayscale(e){for(let t=0;t<e.data.length;t+=4){const s=.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2];e.data.fill(s,t,t+3)}return e}threshold(e,t){for(let s=0;s<e.data.length;s+=4){const i=.299*e.data[s]+.587*e.data[s+1]+.114*e.data[s+2]<t?0:255;e.data.fill(i,s,s+3)}return e}bayer(e,t){const s=[[15,135,45,165],[195,75,225,105],[60,180,30,150],[240,120,210,90]];for(let i=0;i<e.data.length;i+=4){const n=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2],a=i/4%e.width,r=Math.floor(i/4/e.width),o=Math.floor((n+s[a%4][r%4])/2)<t?0:255;e.data.fill(o,i,i+3)}return e}floydsteinberg(e){const t=e.width,s=new Uint8ClampedArray(e.width*e.height);for(let t=0,i=0;i<e.data.length;t++,i+=4)s[t]=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2];for(let i=0,n=0;n<e.data.length;i++,n+=4){const a=s[i]<129?0:255,r=Math.floor((s[i]-a)/16);e.data.fill(a,n,n+3),s[i+1]+=7*r,s[i+t-1]+=3*r,s[i+t]+=5*r,s[i+t+1]+=1*r}return e}atkinson(e){const t=e.width,s=new Uint8ClampedArray(e.width*e.height);for(let t=0,i=0;i<e.data.length;t++,i+=4)s[t]=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2];for(let i=0,n=0;n<e.data.length;i++,n+=4){const a=s[i]<129?0:255,r=Math.floor((s[i]-a)/8);e.data.fill(a,n,n+3),s[i+1]+=r,s[i+2]+=r,s[i+t-1]+=r,s[i+t]+=r,s[i+t+1]+=r,s[i+2*t]+=r}return e}});var f=e(new class{flatten(e,t){for(let s=0;s<e.data.length;s+=4){const i=e.data[s+3],n=255-i;e.data[s]=(i*e.data[s]+n*t[0])/255,e.data[s+1]=(i*e.data[s+1]+n*t[1])/255,e.data[s+2]=(i*e.data[s+2]+n*t[2])/255,e.data[s+3]=255}return e}});const w={cp437:{name:"USA, Standard Europe",languages:["en"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp720:{name:"Arabic",languages:["ar"],offset:128,chars:"éâàçêëèïîّْô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡ًٌٍَُِ≈°∙·√ⁿ²■ "},cp737:{name:"Greek",languages:["el"],offset:128,chars:"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ "},cp775:{name:"Baltic Rim",languages:["et","lt"],offset:128,chars:"ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£Ø×¤ĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’±“¾¶§÷„°∙·¹³²■ "},cp850:{name:"Multilingual",languages:["en"],offset:128,chars:"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´˝˛ˇ˘§÷¸°¨˙űŘř■ "},cp851:{name:"Greek",languages:["el"],offset:128,chars:"ÇüéâäàΆçêëèïîΈÄΉΊ ΌôöΎûùΏÖÜά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ´±υφχ§ψ¸°¨ωϋΰώ■ "},cp852:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´˝˛ˇ˘§÷¸°¨˙űŘř■ "},cp853:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàĉçêëèïîìÄĈÉċĊôöòûùİÖÜĝ£Ĝ×ĵáíóúñÑĞğĤĥ�½Ĵş«»░▒▓│┤ÁÂÀŞ╣║╗╝Żż┐└┴┬├─┼Ŝŝ╚╔╩╦╠═╬¤��ÊËÈıÍÎÏ┘┌█▄�Ì▀ÓßÔÒĠġµĦħÚÛÙŬŭ�´�ℓʼn˘§÷¸°¨˙�³²■ "},cp855:{name:"Cyrillic",languages:["bg"],offset:128,chars:"ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№ыЫзЗшШэЭщЩчЧ§■ "},cp857:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´±�¾¶§÷¸°¨·¹³²■ "},cp858:{name:"Euro",languages:["en"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ "},cp860:{name:"Portuguese",languages:["pt"],offset:128,chars:"ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp861:{name:"Icelandic",languages:["is"],offset:128,chars:"ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp862:{name:"Hebrew",languages:["he"],offset:128,chars:"אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp863:{name:"Canadian French",languages:["fr"],offset:128,chars:"ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp864:{name:"Arabic",languages:["ar"],offset:0,chars:"\0\b\t\n\v\f\r !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�"},cp865:{name:"Nordic",languages:["sv","dk"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp866:{name:"Cyrillic 2",languages:["ru"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ "},cp869:{name:"Greek",languages:["el"],offset:128,chars:"������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄±υφχ§ψ΅°¨ωϋΰώ■ "},cp874:{name:"Thai",languages:["th"],offset:128,chars:"€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"},cp1098:{name:"Farsi",languages:["fa"],offset:128,chars:" ،؛؟ًآﺂاﺎءأﺄؤﺋبﺑﭖﭘتﺗثﺛجﺟﭺﭼ×حﺣخﺧدذرزﮊسﺳشﺷصﺻ«»░▒▓│┤ضﺿﻁﻃ╣║╗╝¤ﻅ┐└┴┬├─┼ﻇع╚╔╩╦╠═╬ ﻊﻋﻌغﻎﻏﻐفﻓ┘┌█▄قﻗ▀ﮎﻛﮒﮔلﻟمﻣنﻧوهﻫﻬﮤﯼﯽﯾـ٠١٢٣٤٥٦٧٨٩■ "},cp1118:{name:"Lithuanian",languages:["lt"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀αβΓπΣσµτΦΘΩδ∞φε⋂≡±≥≤„“÷≈°∙˙√ⁿ²■ "},cp1119:{name:"Lithuanian",languages:["lt"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁё≥≤„“÷≈°∙·√ⁿ²■ "},cp1125:{name:"Ukrainian",languages:["uk"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ "},cp1162:{name:"Thai",languages:["th"],offset:128,chars:"€…‘’“”•–— กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"},cp2001:{name:"Lithuanian KBL or 771",languages:["lt"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█ĄąČčрстуфхцчшщъыьэюяĘęĖėĮįŠšŲųŪūŽž■ "},cp3001:{name:"Estonian 1 or 1116",languages:["et"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤šŠÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµžŽÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ "},cp3002:{name:"Estonian 2",languages:["et"],offset:128,chars:" ¡¢£¤¥¦§¨©ª«¬®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖרÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ"},cp3011:{name:"Latvian 1",languages:["lv"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤Ā╢ņ╕╣║╗╝╜╛┐└┴┬├─┼ā╟╚╔╩╦╠═╬╧Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀αßΓπΣσµτΦΘΩδ∞φε∩ĒēĢķĶļĻžŽ∙·√Ņš■ "},cp3012:{name:"Latvian 2 (modified 866)",languages:["lv"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤Ā╢ņ╕╣║╗╝Ō╛┐└┴┬├─┼ā╟╚╔╩╦╠═╬╧Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀рстуфхцчшщъыьэюяĒēĢķĶļĻžŽō·√Ņš■ "},cp3021:{name:"Bulgarian (MIK)",languages:["bg"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3041:{name:"Maltese ISO 646",languages:["mt"],offset:0,chars:"\0\b\t\n\v\f\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZġżħ^_ċabcdefghijklmnopqrstuvwxyzĠŻĦĊ"},cp3840:{name:"Russian (modified 866)",languages:["ru"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюя≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3841:{name:"Ghost",languages:["ru"],offset:128,chars:"ғәёіїјҝөўүӽӈҹҷє£ҒӘЁІЇЈҜӨЎҮӼӇҸҶЄЪ !\"#$%&'()*+,-./0123456789:;<=>?юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧ∅"},cp3843:{name:"Polish (Mazovia)",languages:["pl"],offset:128,chars:"ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖܢ٥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3844:{name:"Czech (Kamenický)",languages:["cz"],offset:128,chars:"ČüéďäĎŤčěĚĹÍľĺÄÁÉžŽôöÓůÚýÖÜŠĽÝŘťáíóúňŇŮÔšřŕŔ¼§«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3845:{name:"Hungarian (CWI-2)",languages:["hu"],offset:128,chars:"ÇüéâäàåçêëèïîÍÄÁÉæÆőöÓűÚŰÖÜ¢£¥₧ƒáíóúñÑªŐ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3846:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜ¢£¥ŞşáíóúñÑĞğ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3847:{name:"Brazil ABNT",languages:["pt"],offset:256,chars:""},cp3848:{name:"Brazil ABICOMP",languages:["pt"],offset:160,chars:" ÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖŒÙÚÛÜŸ¨£¦§°¡àáâãäçèéêëìíîïñòóôõöœùúûüÿߪº¿±"},iso88591:{name:"Latin 1",languages:["en"],offset:128,chars:" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},iso88592:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:" Ą˘Ł¤ĽŚ§¨ŠŞŤŹŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"},iso88597:{name:"Greek",languages:["el"],offset:128,chars:" ‘’£€₯¦§¨©ͺ«¬�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"},iso885915:{name:"Latin 9",languages:["fr"],offset:128,chars:" ¡¢£€¥Š§š©ª«¬®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},rk1048:{name:"Kazakh",languages:["kk"],offset:128,chars:"ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"},windows1250:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:"€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"},windows1251:{name:"Cyrillic",languages:["ru"],offset:128,chars:"ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"},windows1252:{name:"Latin",languages:["fr"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},windows1253:{name:"Greek",languages:["el"],offset:128,chars:"€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"},windows1254:{name:"Turkish",languages:["tr"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"},windows1255:{name:"Hebrew",languages:["he"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת���"},windows1256:{name:"Arabic",languages:["ar"],offset:128,chars:"€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œں ،¢£¤¥¦§¨©ھ«¬®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûüے"},windows1257:{name:"Baltic Rim",languages:["et","lt"],offset:128,chars:"€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙"},windows1258:{name:"Vietnamese",languages:["vi"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"}},m={en:"The quick brown fox jumps over the lazy dog.",jp:"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム",pt:"O próximo vôo à noite sobre o Atlântico, põe freqüentemente o único médico.",fr:"Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus en voyant leurs drôles d'œufs abîmés.",sv:"Flygande bäckasiner söka strax hwila på mjuka tuvor.",dk:"Quizdeltagerne spiste jordbær med fløde",el:"ξεσκεπάζω την ψυχοφθόρα βδελυγμία",tr:"Pijamalı hasta, yağız şoföre çabucak güvendi.",ru:"Съешь же ещё этих мягких французских булок да выпей чаю",hu:"Árvíztűrő tükörfúrógép",pl:"Pchnąć w tę łódź jeża lub ośm skrzyń fig",cz:"Mohu jíst sklo, neublíží mi.",ar:"أنا قادر على أكل الزجاج و هذا لا يؤلمني.",et:"Ma võin klaasi süüa, see ei tee mulle midagi.",lt:"Aš galiu valgyti stiklą ir jis manęs nežeidžia.",bg:"Мога да ям стъкло, то не ми вреди.",is:"Ég get etið gler án þess að meiða mig.",he:"אני יכול לאכול זכוכית וזה לא מזיק לי.",fa:".من می توانم بدونِ احساس درد شيشه بخورم",uk:"Я можу їсти скло, і воно мені не зашкодить.",vi:"Tôi có thể ăn thủy tinh mà không hại gì.",kk:"қазақша",lv:"Es varu ēst stiklu, tas man nekaitē.",mt:"Nista' niekol il-ħġieġ u ma jagħmilli xejn.",th:"ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ"};class b{static getEncodings(){return Object.keys(w)}static getTestStrings(e){return void 0!==w[e]&&void 0!==w[e].languages?w[e].languages.map((e=>({language:e,string:m[e]}))):[]}static supports(e){return void 0!==w[e]&&void 0!==w[e].chars}static encode(e,t){const s=new Uint8Array(e.length);let i="\0".repeat(128),n=128;void 0!==w[t]&&void 0!==w[t].chars&&(i=w[t].chars,n=w[t].offset);for(let t=0;t<e.length;t++){const a=e.codePointAt(t);if(a<128)s[t]=a;else{const r=i.indexOf(e[t]);-1!==r?s[t]=n+r:a<256&&(a<n||a>=n+i.length)?s[t]=a:s[t]=63}}return s}static autoEncode(e,t){const s=[];let i,n=-1;for(let a=0;a<e.length;a++){const r=e.codePointAt(a);let o,h=0;if(r<128&&(o=i||t[0],h=r),!o&&i){const t=w[i].chars.indexOf(e[a]);-1!==t&&(o=i,h=w[i].offset+t)}if(!o)for(let s=0;s<t.length;s++){const i=w[t[s]].chars.indexOf(e[a]);if(-1!==i){o=t[s],h=w[t[s]].offset+i;break}}o||(o=i||t[0],h=63),i!=o&&(i&&(s[n].bytes=new Uint8Array(s[n].bytes)),n++,s[n]={codepage:o,bytes:[]},i=o),s[n].bytes.push(h)}return i&&(s[n].bytes=new Uint8Array(s[n].bytes)),s}}const _={epson:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp851:11,cp853:12,cp857:13,cp737:14,iso88597:15,windows1252:16,cp866:17,cp852:18,cp858:19,cp720:32,cp775:33,cp855:34,cp861:35,cp862:36,cp864:37,cp869:38,iso88592:39,iso885915:40,cp1098:41,cp1118:42,cp1119:43,cp1125:44,windows1250:45,windows1251:46,windows1253:47,windows1254:48,windows1255:49,windows1256:50,windows1257:51,windows1258:52,rk1048:53},zjiang:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,windows1252:16,cp866:17,cp852:18,cp858:19,windows1255:32,cp861:56,cp855:60,cp857:61,cp862:62,cp864:63,cp737:64,cp851:65,cp869:66,cp1119:68,cp1118:69,windows1250:72,windows1251:73,cp3840:74,cp3843:76,cp3844:77,cp3845:78,cp3846:79,cp3847:80,cp3848:81,cp2001:83,cp3001:84,cp3002:85,cp3011:86,cp3012:87,cp3021:88,cp3041:89,windows1253:90,windows1254:91,windows1256:92,cp720:93,windows1258:94,cp775:95},bixolon:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp851:11,cp858:19},star:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,windows1252:16,cp866:17,cp852:18,cp858:19},citizen:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp852:18,cp866:17,cp857:8,windows1252:16,cp858:19,cp864:40},legacy:{cp437:0,cp737:64,cp850:2,cp775:95,cp852:18,cp855:60,cp857:61,cp858:19,cp860:3,cp861:56,cp862:62,cp863:4,cp864:28,cp865:5,cp866:17,cp869:66,cp936:255,cp949:253,cp950:254,cp1252:16,iso88596:22,shiftjis:252,windows874:30,windows1250:72,windows1251:73,windows1252:71,windows1253:90,windows1254:91,windows1255:32,windows1256:92,windows1257:25,windows1258:94}};class y{constructor(e){this._reset(e)}_reset(e){this._options=Object.assign({width:null,embedded:!1,wordWrap:!0,imageMode:"column",codepageMapping:"epson",codepageCandidates:["cp437","cp858","cp860","cp861","cp863","cp865","cp852","cp857","cp855","cp866","cp869"]},e),this._embedded=this._options.width&&this._options.embedded,this._buffer=[],this._queued=[],this._cursor=0,this._codepage="ascii",this._state={codepage:0,align:"left",bold:!1,italic:!1,underline:!1,invert:!1,width:1,height:1}}_encode(e){if("auto"!=this._codepage)return b.encode(e,this._codepage);let t;t="string"==typeof this._options.codepageMapping?_[this._options.codepageMapping]:this._options.codepageMapping;const s=b.autoEncode(e,this._options.codepageCandidates);let i=0;for(let e=0;e<s.length;e++)i+=3+s[e].bytes.byteLength;const n=new Uint8Array(i);let a=0;for(let e=0;e<s.length;e++)n.set([27,116,t[s[e].codepage]],a),n.set(s[e].bytes,a+3),a+=3+s[e].bytes.byteLength,this._state.codepage=t[s[e].codepage];return n}_queue(e){e.forEach((e=>this._queued.push(e)))}_flush(){if(this._embedded){let e=this._options.width-this._cursor;if("left"==this._state.align&&this._queued.push(new Array(e).fill(32)),"center"==this._state.align){const t=e%2;e>>=1,e>0&&this._queued.push(new Array(e).fill(32)),e+t>0&&this._queued.unshift(new Array(e+t).fill(32))}"right"==this._state.align&&this._queued.unshift(new Array(e).fill(32))}this._buffer=this._buffer.concat(this._queued),this._queued=[],this._cursor=0}_wrap(e,t){if(t||this._options.wordWrap&&this._options.width){const s="-".repeat(this._cursor);return g(t||this._options.width,{lineBreak:"\n",whitespace:"all"})(s+e).substring(this._cursor).split("\n")}return[e]}_restoreState(){this.bold(this._state.bold),this.italic(this._state.italic),this.underline(this._state.underline),this.invert(this._state.invert),this._queue([27,116,this._state.codepage])}_getCodepageIdentifier(e){let t;return t="string"==typeof this._options.codepageMapping?_[this._options.codepageMapping]:this._options.codepageMapping,t[e]}initialize(){return this._queue([27,64]),this._flush(),this}codepage(e){if("auto"===e)return this._codepage=e,this;if(!b.supports(e))throw new Error("Unknown codepage");let t;if(t="string"==typeof this._options.codepageMapping?_[this._options.codepageMapping]:this._options.codepageMapping,void 0===t[e])throw new Error("Codepage not supported by printer");return this._codepage=e,this._state.codepage=t[e],this._queue([27,116,t[e]]),this}text(e,t){const s=this._wrap(e,t);for(let e=0;e<s.length;e++){const t=this._encode(s[e]);this._queue([t]),this._cursor+=s[e].length*this._state.width,this._options.width&&!this._embedded&&(this._cursor=this._cursor%this._options.width),e<s.length-1&&this.newline()}return this}newline(){return this._flush(),this._queue([10,13]),this._embedded&&this._restoreState(),this}line(e,t){return this.text(e,t),this.newline(),this}underline(e){return void 0===e&&(e=!this._state.underline),this._state.underline=e,this._queue([27,45,Number(e)]),this}italic(e){return void 0===e&&(e=!this._state.italic),this._state.italic=e,this._queue([27,52,Number(e)]),this}bold(e){return void 0===e&&(e=!this._state.bold),this._state.bold=e,this._queue([27,69,Number(e)]),this}width(e){if(void 0===e&&(e=1),"number"!=typeof e)throw new Error("Width must be a number");if(e<1||e>8)throw new Error("Width must be between 1 and 8");return this._state.width=e,this._queue([29,33,this._state.height-1|this._state.width-1<<4]),this}height(e){if(void 0===e&&(e=1),"number"!=typeof e)throw new Error("Height must be a number");if(e<1||e>8)throw new Error("Height must be between 1 and 8");return this._state.height=e,this._queue([29,33,this._state.height-1|this._state.width-1<<4]),this}invert(e){return void 0===e&&(e=!this._state.invert),this._state.invert=e,this._queue([29,66,Number(e)]),this}size(e){return e="small"===e?1:0,this._queue([27,77,e]),this}align(e){const t={left:0,center:1,right:2};if(!(e in t))throw new Error("Unknown alignment");return this._state.align=e,this._embedded||this._queue([27,97,t[e]]),this}table(e,t){0!=this._cursor&&this.newline();for(let s=0;s<t.length;s++){const i=[];let n=0;for(let a=0;a<e.length;a++){const r=[];if("string"==typeof t[s][a]){const i=g(e[a].width,{lineBreak:"\n"})(t[s][a]).split("\n");for(let t=0;t<i.length;t++)"right"==e[a].align?r[t]=this._encode(i[t].padStart(e[a].width)):r[t]=this._encode(i[t].padEnd(e[a].width))}if("function"==typeof t[s][a]){const i=new y(Object.assign({},this._options,{width:e[a].width,embedded:!0}));i._codepage=this._codepage,i.align(e[a].align),t[s][a](i);const n=i.encode();let o=[];for(let e=0;e<n.byteLength;e++)e<n.byteLength-1&&10===n[e]&&13===n[e+1]?(r.push(o),o=[],e++):o.push(n[e]);o.length&&r.push(o)}n=Math.max(n,r.length),i[a]=r}for(let t=0;t<e.length;t++)if(i[t].length<n)for(let s=i[t].length;s<n;s++){let s="top";void 0!==e[t].verticalAlign&&(s=e[t].verticalAlign),"bottom"==s?i[t].unshift(new Array(e[t].width).fill(32)):i[t].push(new Array(e[t].width).fill(32))}for(let t=0;t<n;t++){for(let s=0;s<e.length;s++)void 0!==e[s].marginLeft&&this.raw(new Array(e[s].marginLeft).fill(32)),this.raw(i[s][t]),void 0!==e[s].marginRight&&this.raw(new Array(e[s].marginRight).fill(32));this.newline()}}return this}rule(e){return e=Object.assign({style:"single",width:this._options.width||10},e||{}),this._queue([27,116,this._getCodepageIdentifier("cp437"),new Array(e.width).fill("double"===e.style?205:196)]),this._queue([27,116,this._state.codepage]),this.newline(),this}box(e,t){let s;s="double"==(e=Object.assign({style:"single",width:this._options.width||30,marginLeft:0,marginRight:0,paddingLeft:0,paddingRight:0},e||{})).style?[201,187,200,188,205,186]:[218,191,192,217,196,179],0!=this._cursor&&this.newline(),this._restoreState(),this._queue([27,116,this._getCodepageIdentifier("cp437")]),this._queue([new Array(e.marginLeft).fill(32),s[0],new Array(e.width-2).fill(s[4]),s[1],new Array(e.marginRight).fill(32)]),this.newline();const i=[];if("string"==typeof t){const s=g(e.width-2-e.paddingLeft-e.paddingRight,{lineBreak:"\n"})(t).split("\n");for(let t=0;t<s.length;t++)"right"==e.align?i[t]=this._encode(s[t].padStart(e.width-2-e.paddingLeft-e.paddingRight)):i[t]=this._encode(s[t].padEnd(e.width-2-e.paddingLeft-e.paddingRight))}if("function"==typeof t){const s=new y(Object.assign({},this._options,{width:e.width-2-e.paddingLeft-e.paddingRight,embedded:!0}));s._codepage=this._codepage,s.align(e.align),t(s);const n=s.encode();let a=[];for(let e=0;e<n.byteLength;e++)e<n.byteLength-1&&10===n[e]&&13===n[e+1]?(i.push(a),a=[],e++):a.push(n[e]);a.length&&i.push(a)}for(let t=0;t<i.length;t++)this._queue([new Array(e.marginLeft).fill(32),s[5],new Array(e.paddingLeft).fill(32)]),this._queue([i[t]]),this._restoreState(),this._queue([27,116,this._getCodepageIdentifier("cp437")]),this._queue([new Array(e.paddingRight).fill(32),s[5],new Array(e.marginRight).fill(32)]),this.newline();return this._queue([new Array(e.marginLeft).fill(32),s[2],new Array(e.width-2).fill(s[4]),s[3],new Array(e.marginRight).fill(32)]),this._restoreState(),this.newline(),this}barcode(e,t,s){if(this._embedded)throw new Error("Barcodes are not supported in table cells or boxes");const i={upca:0,upce:1,ean13:2,ean8:3,code39:4,coda39:4,itf:5,codabar:6,code93:72,code128:73,"gs1-128":80,"gs1-databar-omni":81,"gs1-databar-truncated":82,"gs1-databar-limited":83,"gs1-databar-expanded":84,"code128-auto":85};if(!(t in i))throw new Error("Symbology not supported by printer");{const n=b.encode(e,"ascii");0!=this._cursor&&this.newline(),this._queue([29,104,s,29,119,"code39"===t?2:3]),"code128"==t&&123!==n[0]?this._queue([29,107,i[t],n.length+2,123,66,n]):i[t]>64?this._queue([29,107,i[t],n.length,n]):this._queue([29,107,i[t],n,0])}return this._flush(),this}qrcode(e,t,s,i){if(this._embedded)throw new Error("QR codes are not supported in table cells or boxes");this._queue([10]);const n={1:49,2:50};if(void 0===t&&(t=2),!(t in n))throw new Error("Model must be 1 or 2");if(this._queue([29,40,107,4,0,49,65,n[t],0]),void 0===s&&(s=6),"number"!=typeof s)throw new Error("Size must be a number");if(s<1||s>8)throw new Error("Size must be between 1 and 8");this._queue([29,40,107,3,0,49,67,s]);const a={l:48,m:49,q:50,h:51};if(void 0===i&&(i="m"),!(i in a))throw new Error("Error level must be l, m, q or h");this._queue([29,40,107,3,0,49,69,a[i]]);const r=b.encode(e,"iso88591"),o=r.length+3;return this._queue([29,40,107,o%255,o/255,49,80,48,r]),this._queue([29,40,107,3,0,49,81,48]),this._flush(),this}image(e,t,s,i,n){if(this._embedded)throw new Error("Images are not supported in table cells or boxes");if(t%8!=0)throw new Error("Width must be a multiple of 8");if(s%8!=0)throw new Error("Height must be a multiple of 8");void 0===i&&(i="threshold"),void 0===n&&(n=128);const a=function(e,t){return Object.assign(document.createElement("canvas"),{width:e,height:t})}(t,s),r=a.getContext("2d");r.drawImage(e,0,0,t,s);let o=r.getImageData(0,0,t,s);switch(o=f.flatten(o,[255,255,255]),i){case"threshold":o=u.threshold(o,n);break;case"bayer":o=u.bayer(o,n);break;case"floydsteinberg":o=u.floydsteinberg(o);break;case"atkinson":o=u.atkinson(o)}const h=(e,i)=>e<t&&i<s?o.data[4*(t*i+e)]>0?0:1:0,l=(e,t)=>{const s=new Uint8Array(e*t>>3);for(let i=0;i<t;i++)for(let t=0;t<e;t+=8)for(let n=0;n<8;n++)s[i*(e>>3)+(t>>3)]|=h(t+n,i)<<7-n;return s};return 0!=this._cursor&&this.newline(),"column"==this._options.imageMode&&(this._queue([27,51,36]),((e,t)=>{const s=[];for(let i=0;i<Math.ceil(t/24);i++){const t=new Uint8Array(3*e);for(let s=0;s<e;s++)for(let e=0;e<3;e++)for(let n=0;n<8;n++)t[3*s+e]|=h(s,24*i+n+8*e)<<7-n;s.push(t)}return s})(t,s).forEach((e=>{this._queue([27,42,33,255&t,t>>8&255,e,10])})),this._queue([27,50])),"raster"==this._options.imageMode&&this._queue([29,118,48,0,t>>3&255,t>>3>>8&255,255&s,s>>8&255,l(t,s)]),this._flush(),this}cut(e){if(this._embedded)throw new Error("Cut is not supported in table cells or boxes");let t=0;return"partial"==e&&(t=1),this._queue([29,86,t]),this}pulse(e,t,s){if(this._embedded)throw new Error("Pulse is not supported in table cells or boxes");return void 0===e&&(e=0),void 0===t&&(t=100),void 0===s&&(s=500),t=Math.min(500,Math.round(t/2)),s=Math.min(500,Math.round(s/2)),this._queue([27,112,e?1:0,255&t,255&s]),this}raw(e){return this._queue(e),this}encode(){this._flush();let e=0;this._buffer.forEach((t=>{"number"==typeof t?e++:e+=t.length}));const t=new Uint8Array(e);let s=0;return this._buffer.forEach((e=>{"number"==typeof e?(t[s]=e,s++):(t.set(e,s),s+=e.length)})),this._reset(),t}}export{y as default}; |
| import linewrap from 'linewrap'; | ||
| import { createCanvas } from 'canvas'; | ||
| import Dither from 'canvas-dither'; | ||
| import Flatten from 'canvas-flatten'; | ||
| import CodepageEncoder from 'codepage-encoder'; | ||
| const codepageMappings = { | ||
| epson: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp851': 0x0b, | ||
| 'cp853': 0x0c, | ||
| 'cp857': 0x0d, | ||
| 'cp737': 0x0e, | ||
| 'iso88597': 0x0f, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| 'cp720': 0x20, | ||
| 'cp775': 0x21, | ||
| 'cp855': 0x22, | ||
| 'cp861': 0x23, | ||
| 'cp862': 0x24, | ||
| 'cp864': 0x25, | ||
| 'cp869': 0x26, | ||
| 'iso88592': 0x27, | ||
| 'iso885915': 0x28, | ||
| 'cp1098': 0x29, | ||
| 'cp1118': 0x2a, | ||
| 'cp1119': 0x2b, | ||
| 'cp1125': 0x2c, | ||
| 'windows1250': 0x2d, | ||
| 'windows1251': 0x2e, | ||
| 'windows1253': 0x2f, | ||
| 'windows1254': 0x30, | ||
| 'windows1255': 0x31, | ||
| 'windows1256': 0x32, | ||
| 'windows1257': 0x33, | ||
| 'windows1258': 0x34, | ||
| 'rk1048': 0x35, | ||
| }, | ||
| zjiang: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| 'windows1255': 0x20, | ||
| 'cp861': 0x38, | ||
| 'cp855': 0x3c, | ||
| 'cp857': 0x3d, | ||
| 'cp862': 0x3e, | ||
| 'cp864': 0x3f, | ||
| 'cp737': 0x40, | ||
| 'cp851': 0x41, | ||
| 'cp869': 0x42, | ||
| 'cp1119': 0x44, | ||
| 'cp1118': 0x45, | ||
| 'windows1250': 0x48, | ||
| 'windows1251': 0x49, | ||
| 'cp3840': 0x4a, | ||
| 'cp3843': 0x4c, | ||
| 'cp3844': 0x4d, | ||
| 'cp3845': 0x4e, | ||
| 'cp3846': 0x4f, | ||
| 'cp3847': 0x50, | ||
| 'cp3848': 0x51, | ||
| 'cp2001': 0x53, | ||
| 'cp3001': 0x54, | ||
| 'cp3002': 0x55, | ||
| 'cp3011': 0x56, | ||
| 'cp3012': 0x57, | ||
| 'cp3021': 0x58, | ||
| 'cp3041': 0x59, | ||
| 'windows1253': 0x5a, | ||
| 'windows1254': 0x5b, | ||
| 'windows1256': 0x5c, | ||
| 'cp720': 0x5d, | ||
| 'windows1258': 0x5e, | ||
| 'cp775': 0x5f, | ||
| }, | ||
| bixolon: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp851': 0x0b, | ||
| 'cp858': 0x13, | ||
| }, | ||
| star: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| }, | ||
| citizen: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp852': 0x12, | ||
| 'cp866': 0x11, | ||
| 'cp857': 0x08, | ||
| 'windows1252': 0x10, | ||
| 'cp858': 0x13, | ||
| 'cp864': 0x28, | ||
| }, | ||
| legacy: { | ||
| 'cp437': 0x00, | ||
| 'cp737': 0x40, | ||
| 'cp850': 0x02, | ||
| 'cp775': 0x5f, | ||
| 'cp852': 0x12, | ||
| 'cp855': 0x3c, | ||
| 'cp857': 0x3d, | ||
| 'cp858': 0x13, | ||
| 'cp860': 0x03, | ||
| 'cp861': 0x38, | ||
| 'cp862': 0x3e, | ||
| 'cp863': 0x04, | ||
| 'cp864': 0x1c, | ||
| 'cp865': 0x05, | ||
| 'cp866': 0x11, | ||
| 'cp869': 0x42, | ||
| 'cp936': 0xff, | ||
| 'cp949': 0xfd, | ||
| 'cp950': 0xfe, | ||
| 'cp1252': 0x10, | ||
| 'iso88596': 0x16, | ||
| 'shiftjis': 0xfc, | ||
| 'windows874': 0x1e, | ||
| 'windows1250': 0x48, | ||
| 'windows1251': 0x49, | ||
| 'windows1252': 0x47, | ||
| 'windows1253': 0x5a, | ||
| 'windows1254': 0x5b, | ||
| 'windows1255': 0x20, | ||
| 'windows1256': 0x5c, | ||
| 'windows1257': 0x19, | ||
| 'windows1258': 0x5e, | ||
| }, | ||
| }; | ||
| /** | ||
| * Create a byte stream based on commands for ESC/POS printers | ||
| */ | ||
| class EscPosEncoder { | ||
| /** | ||
| * Create a new object | ||
| * | ||
| * @param {object} options Object containing configuration options | ||
| */ | ||
| constructor(options) { | ||
| this._reset(options); | ||
| } | ||
| /** | ||
| * Reset the state of the object | ||
| * | ||
| * @param {object} options Object containing configuration options | ||
| */ | ||
| _reset(options) { | ||
| this._options = Object.assign({ | ||
| width: null, | ||
| embedded: false, | ||
| wordWrap: true, | ||
| imageMode: 'column', | ||
| codepageMapping: 'epson', | ||
| codepageCandidates: [ | ||
| 'cp437', 'cp858', 'cp860', 'cp861', 'cp863', 'cp865', | ||
| 'cp852', 'cp857', 'cp855', 'cp866', 'cp869', | ||
| ], | ||
| }, options); | ||
| this._embedded = this._options.width && this._options.embedded; | ||
| this._buffer = []; | ||
| this._queued = []; | ||
| this._cursor = 0; | ||
| this._codepage = 'ascii'; | ||
| this._state = { | ||
| 'codepage': 0, | ||
| 'align': 'left', | ||
| 'bold': false, | ||
| 'italic': false, | ||
| 'underline': false, | ||
| 'invert': false, | ||
| 'width': 1, | ||
| 'height': 1, | ||
| }; | ||
| } | ||
| /** | ||
| * Encode a string with the current code page | ||
| * | ||
| * @param {string} value String to encode | ||
| * @return {object} Encoded string as a ArrayBuffer | ||
| * | ||
| */ | ||
| _encode(value) { | ||
| if (this._codepage != 'auto') { | ||
| return CodepageEncoder.encode(value, this._codepage); | ||
| } | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| const fragments = CodepageEncoder.autoEncode(value, this._options.codepageCandidates); | ||
| let length = 0; | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| length += 3 + fragments[f].bytes.byteLength; | ||
| } | ||
| const buffer = new Uint8Array(length); | ||
| let i = 0; | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| buffer.set([0x1b, 0x74, codepages[fragments[f].codepage]], i); | ||
| buffer.set(fragments[f].bytes, i + 3); | ||
| i += 3 + fragments[f].bytes.byteLength; | ||
| this._state.codepage = codepages[fragments[f].codepage]; | ||
| } | ||
| return buffer; | ||
| } | ||
| /** | ||
| * Add commands to the queue | ||
| * | ||
| * @param {array} value Add array of numbers, arrays, buffers or Uint8Arrays to add to the buffer | ||
| * | ||
| */ | ||
| _queue(value) { | ||
| value.forEach((item) => this._queued.push(item)); | ||
| } | ||
| /** | ||
| * Flush current queue to the buffer | ||
| * | ||
| */ | ||
| _flush() { | ||
| if (this._embedded) { | ||
| let indent = this._options.width - this._cursor; | ||
| if (this._state.align == 'left') { | ||
| this._queued.push((new Array(indent)).fill(0x20)); | ||
| } | ||
| if (this._state.align == 'center') { | ||
| const remainder = indent % 2; | ||
| indent = indent >> 1; | ||
| if (indent > 0) { | ||
| this._queued.push((new Array(indent)).fill(0x20)); | ||
| } | ||
| if (indent + remainder > 0) { | ||
| this._queued.unshift((new Array(indent + remainder)).fill(0x20)); | ||
| } | ||
| } | ||
| if (this._state.align == 'right') { | ||
| this._queued.unshift((new Array(indent)).fill(0x20)); | ||
| } | ||
| } | ||
| this._buffer = this._buffer.concat(this._queued); | ||
| this._queued = []; | ||
| this._cursor = 0; | ||
| } | ||
| /** | ||
| * Wrap the text while respecting the position of the cursor | ||
| * | ||
| * @param {string} value String to wrap after the width of the paper has been reached | ||
| * @param {number} position Position on which to force a wrap | ||
| * @return {array} Array with each line | ||
| */ | ||
| _wrap(value, position) { | ||
| if (position || (this._options.wordWrap && this._options.width)) { | ||
| const indent = '-'.repeat(this._cursor); | ||
| const w = linewrap(position || this._options.width, {lineBreak: '\n', whitespace: 'all'}); | ||
| const result = w(indent + value).substring(this._cursor).split('\n'); | ||
| return result; | ||
| } | ||
| return [value]; | ||
| } | ||
| /** | ||
| * Restore styles and codepages after drawing boxes or lines | ||
| */ | ||
| _restoreState() { | ||
| this.bold(this._state.bold); | ||
| this.italic(this._state.italic); | ||
| this.underline(this._state.underline); | ||
| this.invert(this._state.invert); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._state.codepage, | ||
| ]); | ||
| } | ||
| /** | ||
| * Get code page identifier for the specified code page and mapping | ||
| * | ||
| * @param {string} codepage Required code page | ||
| * @return {number} Identifier for the current printer according to the specified mapping | ||
| */ | ||
| _getCodepageIdentifier(codepage) { | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| return codepages[codepage]; | ||
| } | ||
| /** | ||
| * Initialize the printer | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| initialize() { | ||
| this._queue([ | ||
| 0x1b, 0x40, | ||
| ]); | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change the code page | ||
| * | ||
| * @param {string} codepage The codepage that we set the printer to | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| codepage(codepage) { | ||
| if (codepage === 'auto') { | ||
| this._codepage = codepage; | ||
| return this; | ||
| } | ||
| if (!CodepageEncoder.supports(codepage)) { | ||
| throw new Error('Unknown codepage'); | ||
| } | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| if (typeof codepages[codepage] !== 'undefined') { | ||
| this._codepage = codepage; | ||
| this._state.codepage = codepages[codepage]; | ||
| this._queue([ | ||
| 0x1b, 0x74, codepages[codepage], | ||
| ]); | ||
| } else { | ||
| throw new Error('Codepage not supported by printer'); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print text | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| text(value, wrap) { | ||
| const lines = this._wrap(value, wrap); | ||
| for (let l = 0; l < lines.length; l++) { | ||
| const bytes = this._encode(lines[l]); | ||
| this._queue([ | ||
| bytes, | ||
| ]); | ||
| this._cursor += (lines[l].length * this._state.width); | ||
| if (this._options.width && !this._embedded) { | ||
| this._cursor = this._cursor % this._options.width; | ||
| } | ||
| if (l < lines.length - 1) { | ||
| this.newline(); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print a newline | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| newline() { | ||
| this._flush(); | ||
| this._queue([ | ||
| 0x0a, 0x0d, | ||
| ]); | ||
| if (this._embedded) { | ||
| this._restoreState(); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print text, followed by a newline | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| line(value, wrap) { | ||
| this.text(value, wrap); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Underline text | ||
| * | ||
| * @param {boolean|number} value true to turn on underline, false to turn off, or 2 for double underline | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| underline(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.underline; | ||
| } | ||
| this._state.underline = value; | ||
| this._queue([ | ||
| 0x1b, 0x2d, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Italic text | ||
| * | ||
| * @param {boolean} value true to turn on italic, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| italic(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.italic; | ||
| } | ||
| this._state.italic = value; | ||
| this._queue([ | ||
| 0x1b, 0x34, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Bold text | ||
| * | ||
| * @param {boolean} value true to turn on bold, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| bold(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.bold; | ||
| } | ||
| this._state.bold = value; | ||
| this._queue([ | ||
| 0x1b, 0x45, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change width of text | ||
| * | ||
| * @param {number} width The width of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| width(width) { | ||
| if (typeof width === 'undefined') { | ||
| width = 1; | ||
| } | ||
| if (typeof width !== 'number') { | ||
| throw new Error('Width must be a number'); | ||
| } | ||
| if (width < 1 || width > 8) { | ||
| throw new Error('Width must be between 1 and 8'); | ||
| } | ||
| this._state.width = width; | ||
| this._queue([ | ||
| 0x1d, 0x21, (this._state.height - 1) | (this._state.width - 1) << 4, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change height of text | ||
| * | ||
| * @param {number} height The height of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| height(height) { | ||
| if (typeof height === 'undefined') { | ||
| height = 1; | ||
| } | ||
| if (typeof height !== 'number') { | ||
| throw new Error('Height must be a number'); | ||
| } | ||
| if (height < 1 || height > 8) { | ||
| throw new Error('Height must be between 1 and 8'); | ||
| } | ||
| this._state.height = height; | ||
| this._queue([ | ||
| 0x1d, 0x21, (this._state.height - 1) | (this._state.width - 1) << 4, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Invert text | ||
| * | ||
| * @param {boolean} value true to turn on white text on black, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| invert(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.invert; | ||
| } | ||
| this._state.invert = value; | ||
| this._queue([ | ||
| 0x1d, 0x42, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change text size | ||
| * | ||
| * @param {string} value small or normal | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| size(value) { | ||
| if (value === 'small') { | ||
| value = 0x01; | ||
| } else { | ||
| value = 0x00; | ||
| } | ||
| this._queue([ | ||
| 0x1b, 0x4d, value, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change text alignment | ||
| * | ||
| * @param {string} value left, center or right | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| align(value) { | ||
| const alignments = { | ||
| 'left': 0x00, | ||
| 'center': 0x01, | ||
| 'right': 0x02, | ||
| }; | ||
| if (value in alignments) { | ||
| this._state.align = value; | ||
| if (!this._embedded) { | ||
| this._queue([ | ||
| 0x1b, 0x61, alignments[value], | ||
| ]); | ||
| } | ||
| } else { | ||
| throw new Error('Unknown alignment'); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a table | ||
| * | ||
| * @param {array} columns The column definitions | ||
| * @param {array} data Array containing rows. Each row is an array containing cells. | ||
| * Each cell can be a string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| table(columns, data) { | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| for (let r = 0; r < data.length; r++) { | ||
| const lines = []; | ||
| let maxLines = 0; | ||
| for (let c = 0; c < columns.length; c++) { | ||
| const cell = []; | ||
| if (typeof data[r][c] === 'string') { | ||
| const w = linewrap(columns[c].width, {lineBreak: '\n'}); | ||
| const fragments = w(data[r][c]).split('\n'); | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| if (columns[c].align == 'right') { | ||
| cell[f] = this._encode(fragments[f].padStart(columns[c].width)); | ||
| } else { | ||
| cell[f] = this._encode(fragments[f].padEnd(columns[c].width)); | ||
| } | ||
| } | ||
| } | ||
| if (typeof data[r][c] === 'function') { | ||
| const columnEncoder = new EscPosEncoder(Object.assign({}, this._options, { | ||
| width: columns[c].width, | ||
| embedded: true, | ||
| })); | ||
| columnEncoder._codepage = this._codepage; | ||
| columnEncoder.align(columns[c].align); | ||
| data[r][c](columnEncoder); | ||
| const encoded = columnEncoder.encode(); | ||
| let fragment = []; | ||
| for (let e = 0; e < encoded.byteLength; e++) { | ||
| if (e < encoded.byteLength - 1) { | ||
| if (encoded[e] === 0x0a && encoded[e + 1] === 0x0d) { | ||
| cell.push(fragment); | ||
| fragment = []; | ||
| e++; | ||
| continue; | ||
| } | ||
| } | ||
| fragment.push(encoded[e]); | ||
| } | ||
| if (fragment.length) { | ||
| cell.push(fragment); | ||
| } | ||
| } | ||
| maxLines = Math.max(maxLines, cell.length); | ||
| lines[c] = cell; | ||
| } | ||
| for (let c = 0; c < columns.length; c++) { | ||
| if (lines[c].length < maxLines) { | ||
| for (let p = lines[c].length; p < maxLines; p++) { | ||
| let verticalAlign = 'top'; | ||
| if (typeof columns[c].verticalAlign !== 'undefined') { | ||
| verticalAlign = columns[c].verticalAlign; | ||
| } | ||
| if (verticalAlign == 'bottom') { | ||
| lines[c].unshift((new Array(columns[c].width)).fill(0x20)); | ||
| } else { | ||
| lines[c].push((new Array(columns[c].width)).fill(0x20)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| for (let l = 0; l < maxLines; l++) { | ||
| for (let c = 0; c < columns.length; c++) { | ||
| if (typeof columns[c].marginLeft !== 'undefined') { | ||
| this.raw((new Array(columns[c].marginLeft)).fill(0x20)); | ||
| } | ||
| this.raw(lines[c][l]); | ||
| if (typeof columns[c].marginRight !== 'undefined') { | ||
| this.raw((new Array(columns[c].marginRight)).fill(0x20)); | ||
| } | ||
| } | ||
| this.newline(); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a horizontal rule | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the line, either single or double | ||
| * - width: The width of the line, by default the width of the paper | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| rule(options) { | ||
| options = Object.assign({ | ||
| style: 'single', | ||
| width: this._options.width || 10, | ||
| }, options || {}); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| (new Array(options.width)).fill(options.style === 'double' ? 0xcd : 0xc4), | ||
| ]); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._state.codepage, | ||
| ]); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a box | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the border, either single or double | ||
| * - width: The width of the box, by default the width of the paper | ||
| * - marginLeft: Space between the left border and the left edge | ||
| * - marginRight: Space between the right border and the right edge | ||
| * - paddingLeft: Space between the contents and the left border of the box | ||
| * - paddingRight: Space between the contents and the right border of the box | ||
| * @param {string|function} contents A string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| box(options, contents) { | ||
| options = Object.assign({ | ||
| style: 'single', | ||
| width: this._options.width || 30, | ||
| marginLeft: 0, | ||
| marginRight: 0, | ||
| paddingLeft: 0, | ||
| paddingRight: 0, | ||
| }, options || {}); | ||
| let elements; | ||
| if (options.style == 'double') { | ||
| elements = [0xc9, 0xbb, 0xc8, 0xbc, 0xcd, 0xba]; // ╔╗╚╝═║ | ||
| } else { | ||
| elements = [0xda, 0xbf, 0xc0, 0xd9, 0xc4, 0xb3]; // ┌┐└┘─│ | ||
| } | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| this._restoreState(); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| ]); | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[0], | ||
| new Array(options.width - 2).fill(elements[4]), | ||
| elements[1], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this.newline(); | ||
| const cell = []; | ||
| if (typeof contents === 'string') { | ||
| const w = linewrap(options.width - 2 - options.paddingLeft - options.paddingRight, {lineBreak: '\n'}); | ||
| const fragments = w(contents).split('\n'); | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| if (options.align == 'right') { | ||
| cell[f] = this._encode(fragments[f].padStart(options.width - 2 - options.paddingLeft - options.paddingRight)); | ||
| } else { | ||
| cell[f] = this._encode(fragments[f].padEnd(options.width - 2 - options.paddingLeft - options.paddingRight)); | ||
| } | ||
| } | ||
| } | ||
| if (typeof contents === 'function') { | ||
| const columnEncoder = new EscPosEncoder(Object.assign({}, this._options, { | ||
| width: options.width - 2 - options.paddingLeft - options.paddingRight, | ||
| embedded: true, | ||
| })); | ||
| columnEncoder._codepage = this._codepage; | ||
| columnEncoder.align(options.align); | ||
| contents(columnEncoder); | ||
| const encoded = columnEncoder.encode(); | ||
| let fragment = []; | ||
| for (let e = 0; e < encoded.byteLength; e++) { | ||
| if (e < encoded.byteLength - 1) { | ||
| if (encoded[e] === 0x0a && encoded[e + 1] === 0x0d) { | ||
| cell.push(fragment); | ||
| fragment = []; | ||
| e++; | ||
| continue; | ||
| } | ||
| } | ||
| fragment.push(encoded[e]); | ||
| } | ||
| if (fragment.length) { | ||
| cell.push(fragment); | ||
| } | ||
| } | ||
| for (let c = 0; c < cell.length; c++) { | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[5], | ||
| new Array(options.paddingLeft).fill(0x20), | ||
| ]); | ||
| this._queue([ | ||
| cell[c], | ||
| ]); | ||
| this._restoreState(); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| ]); | ||
| this._queue([ | ||
| new Array(options.paddingRight).fill(0x20), | ||
| elements[5], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this.newline(); | ||
| } | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[2], | ||
| new Array(options.width - 2).fill(elements[4]), | ||
| elements[3], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this._restoreState(); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Barcode | ||
| * | ||
| * @param {string} value the value of the barcode | ||
| * @param {string} symbology the type of the barcode | ||
| * @param {number} height height of the barcode | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| barcode(value, symbology, height) { | ||
| if (this._embedded) { | ||
| throw new Error('Barcodes are not supported in table cells or boxes'); | ||
| } | ||
| const symbologies = { | ||
| 'upca': 0x00, | ||
| 'upce': 0x01, | ||
| 'ean13': 0x02, | ||
| 'ean8': 0x03, | ||
| 'code39': 0x04, | ||
| 'coda39': 0x04, /* typo, leave here for backwards compatibility */ | ||
| 'itf': 0x05, | ||
| 'codabar': 0x06, | ||
| 'code93': 0x48, | ||
| 'code128': 0x49, | ||
| 'gs1-128': 0x50, | ||
| 'gs1-databar-omni': 0x51, | ||
| 'gs1-databar-truncated': 0x52, | ||
| 'gs1-databar-limited': 0x53, | ||
| 'gs1-databar-expanded': 0x54, | ||
| 'code128-auto': 0x55, | ||
| }; | ||
| if (symbology in symbologies) { | ||
| const bytes = CodepageEncoder.encode(value, 'ascii'); | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x68, height, | ||
| 0x1d, 0x77, symbology === 'code39' ? 0x02 : 0x03, | ||
| ]); | ||
| if (symbology == 'code128' && bytes[0] !== 0x7b) { | ||
| /* Not yet encodeded Code 128, assume data is Code B, which is similar to ASCII without control chars */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes.length + 2, | ||
| 0x7b, 0x42, | ||
| bytes, | ||
| ]); | ||
| } else if (symbologies[symbology] > 0x40) { | ||
| /* Function B symbologies */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes.length, | ||
| bytes, | ||
| ]); | ||
| } else { | ||
| /* Function A symbologies */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes, | ||
| 0x00, | ||
| ]); | ||
| } | ||
| } else { | ||
| throw new Error('Symbology not supported by printer'); | ||
| } | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * QR code | ||
| * | ||
| * @param {string} value the value of the qr code | ||
| * @param {number} model model of the qrcode, either 1 or 2 | ||
| * @param {number} size size of the qrcode, a value between 1 and 8 | ||
| * @param {string} errorlevel the amount of error correction used, either 'l', 'm', 'q', 'h' | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| qrcode(value, model, size, errorlevel) { | ||
| if (this._embedded) { | ||
| throw new Error('QR codes are not supported in table cells or boxes'); | ||
| } | ||
| /* Force printing the print buffer and moving to a new line */ | ||
| this._queue([ | ||
| 0x0a, | ||
| ]); | ||
| /* Model */ | ||
| const models = { | ||
| 1: 0x31, | ||
| 2: 0x32, | ||
| }; | ||
| if (typeof model === 'undefined') { | ||
| model = 2; | ||
| } | ||
| if (model in models) { | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x04, 0x00, 0x31, 0x41, models[model], 0x00, | ||
| ]); | ||
| } else { | ||
| throw new Error('Model must be 1 or 2'); | ||
| } | ||
| /* Size */ | ||
| if (typeof size === 'undefined') { | ||
| size = 6; | ||
| } | ||
| if (typeof size !== 'number') { | ||
| throw new Error('Size must be a number'); | ||
| } | ||
| if (size < 1 || size > 8) { | ||
| throw new Error('Size must be between 1 and 8'); | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, size, | ||
| ]); | ||
| /* Error level */ | ||
| const errorlevels = { | ||
| 'l': 0x30, | ||
| 'm': 0x31, | ||
| 'q': 0x32, | ||
| 'h': 0x33, | ||
| }; | ||
| if (typeof errorlevel === 'undefined') { | ||
| errorlevel = 'm'; | ||
| } | ||
| if (errorlevel in errorlevels) { | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x45, errorlevels[errorlevel], | ||
| ]); | ||
| } else { | ||
| throw new Error('Error level must be l, m, q or h'); | ||
| } | ||
| /* Data */ | ||
| const bytes = CodepageEncoder.encode(value, 'iso88591'); | ||
| const length = bytes.length + 3; | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, length % 0xff, length / 0xff, 0x31, 0x50, 0x30, bytes, | ||
| ]); | ||
| /* Print QR code */ | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30, | ||
| ]); | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Image | ||
| * | ||
| * @param {object} element an element, like a canvas or image that needs to be printed | ||
| * @param {number} width width of the image on the printer | ||
| * @param {number} height height of the image on the printer | ||
| * @param {string} algorithm the dithering algorithm for making the image black and white | ||
| * @param {number} threshold threshold for the dithering algorithm | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| image(element, width, height, algorithm, threshold) { | ||
| if (this._embedded) { | ||
| throw new Error('Images are not supported in table cells or boxes'); | ||
| } | ||
| if (width % 8 !== 0) { | ||
| throw new Error('Width must be a multiple of 8'); | ||
| } | ||
| if (height % 8 !== 0) { | ||
| throw new Error('Height must be a multiple of 8'); | ||
| } | ||
| if (typeof algorithm === 'undefined') { | ||
| algorithm = 'threshold'; | ||
| } | ||
| if (typeof threshold === 'undefined') { | ||
| threshold = 128; | ||
| } | ||
| const canvas = createCanvas(width, height); | ||
| const context = canvas.getContext('2d'); | ||
| context.drawImage(element, 0, 0, width, height); | ||
| let image = context.getImageData(0, 0, width, height); | ||
| image = Flatten.flatten(image, [0xff, 0xff, 0xff]); | ||
| switch (algorithm) { | ||
| case 'threshold': image = Dither.threshold(image, threshold); break; | ||
| case 'bayer': image = Dither.bayer(image, threshold); break; | ||
| case 'floydsteinberg': image = Dither.floydsteinberg(image); break; | ||
| case 'atkinson': image = Dither.atkinson(image); break; | ||
| } | ||
| const getPixel = (x, y) => x < width && y < height ? (image.data[((width * y) + x) * 4] > 0 ? 0 : 1) : 0; | ||
| const getColumnData = (width, height) => { | ||
| const data = []; | ||
| for (let s = 0; s < Math.ceil(height / 24); s++) { | ||
| const bytes = new Uint8Array(width * 3); | ||
| for (let x = 0; x < width; x++) { | ||
| for (let c = 0; c < 3; c++) { | ||
| for (let b = 0; b < 8; b++) { | ||
| bytes[(x * 3) + c] |= getPixel(x, (s * 24) + b + (8 * c)) << (7 - b); | ||
| } | ||
| } | ||
| } | ||
| data.push(bytes); | ||
| } | ||
| return data; | ||
| }; | ||
| const getRowData = (width, height) => { | ||
| const bytes = new Uint8Array((width * height) >> 3); | ||
| for (let y = 0; y < height; y++) { | ||
| for (let x = 0; x < width; x = x + 8) { | ||
| for (let b = 0; b < 8; b++) { | ||
| bytes[(y * (width >> 3)) + (x >> 3)] |= getPixel(x + b, y) << (7 - b); | ||
| } | ||
| } | ||
| } | ||
| return bytes; | ||
| }; | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| /* Encode images with ESC * */ | ||
| if (this._options.imageMode == 'column') { | ||
| this._queue([ | ||
| 0x1b, 0x33, 0x24, | ||
| ]); | ||
| getColumnData(width, height).forEach((bytes) => { | ||
| this._queue([ | ||
| 0x1b, 0x2a, 0x21, | ||
| (width) & 0xff, (((width) >> 8) & 0xff), | ||
| bytes, | ||
| 0x0a, | ||
| ]); | ||
| }); | ||
| this._queue([ | ||
| 0x1b, 0x32, | ||
| ]); | ||
| } | ||
| /* Encode images with GS v */ | ||
| if (this._options.imageMode == 'raster') { | ||
| this._queue([ | ||
| 0x1d, 0x76, 0x30, 0x00, | ||
| (width >> 3) & 0xff, (((width >> 3) >> 8) & 0xff), | ||
| height & 0xff, ((height >> 8) & 0xff), | ||
| getRowData(width, height), | ||
| ]); | ||
| } | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Cut paper | ||
| * | ||
| * @param {string} value full or partial. When not specified a full cut will be assumed | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| cut(value) { | ||
| if (this._embedded) { | ||
| throw new Error('Cut is not supported in table cells or boxes'); | ||
| } | ||
| let data = 0x00; | ||
| if (value == 'partial') { | ||
| data = 0x01; | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x56, data, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Pulse | ||
| * | ||
| * @param {number} device 0 or 1 for on which pin the device is connected, default of 0 | ||
| * @param {number} on Time the pulse is on in milliseconds, default of 100 | ||
| * @param {number} off Time the pulse is off in milliseconds, default of 500 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| pulse(device, on, off) { | ||
| if (this._embedded) { | ||
| throw new Error('Pulse is not supported in table cells or boxes'); | ||
| } | ||
| if (typeof device === 'undefined') { | ||
| device = 0; | ||
| } | ||
| if (typeof on === 'undefined') { | ||
| on = 100; | ||
| } | ||
| if (typeof off === 'undefined') { | ||
| off = 500; | ||
| } | ||
| on = Math.min(500, Math.round(on / 2)); | ||
| off = Math.min(500, Math.round(off / 2)); | ||
| this._queue([ | ||
| 0x1b, 0x70, device ? 1 : 0, on & 0xff, off & 0xff, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Add raw printer commands | ||
| * | ||
| * @param {array} data raw bytes to be included | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| raw(data) { | ||
| this._queue(data); | ||
| return this; | ||
| } | ||
| /** | ||
| * Encode all previous commands | ||
| * | ||
| * @return {Uint8Array} Return the encoded bytes | ||
| * | ||
| */ | ||
| encode() { | ||
| this._flush(); | ||
| let length = 0; | ||
| this._buffer.forEach((item) => { | ||
| if (typeof item === 'number') { | ||
| length++; | ||
| } else { | ||
| length += item.length; | ||
| } | ||
| }); | ||
| const result = new Uint8Array(length); | ||
| let index = 0; | ||
| this._buffer.forEach((item) => { | ||
| if (typeof item === 'number') { | ||
| result[index] = item; | ||
| index++; | ||
| } else { | ||
| result.set(item, index); | ||
| index += item.length; | ||
| } | ||
| }); | ||
| this._reset(); | ||
| return result; | ||
| } | ||
| } | ||
| export { EscPosEncoder as default }; |
| !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).EscPosEncoder=t()}(this,(function(){"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t={exports:{}},s={html:{skipScheme:"html",lineBreakScheme:"html",whitespace:"collapse"}},i=/<\s*br(?:[\s/]*|\s[^>]*)>/gi,n={unix:[/\n/g,"\n"],dos:[/\r\n/g,"\r\n"],mac:[/\r/g,"\r"],html:[i,"<br>"],xhtml:[i,"<br/>"]},a={"ansi-color":/\x1B\[[^m]*m/g,html:/<[^>]*>/g,bbcode:/\[[^]]*\]/g},r={soft:1,hard:1},o={collapse:1,default:1,line:1,all:1},h={all:1,multi:1,none:1},l=/([sm])(\d+)/,c=/[-/\\^$*+?.()|[\]{}]/g;function p(e){return e.replace(c,"\\$&")}var d=t.exports=function(e,t,i){"object"==typeof e&&(e=(i=e).start,t=i.stop),"object"==typeof t&&(i=t,e=e||i.start,t=void 0),t||(t=e,e=0),i||(i={});var c,d,g,u,f,w,m,b,_,y,v,k,E,x,L,q,j,A,I="soft",B="default",M=4,R="all",S="",T="";if(c=i.preset)for(c instanceof Array||(c=[c]),A=0;A<c.length;A++){if(!(q=s[c[A]]))throw new TypeError('preset must be one of "'+Object.keys(s).join('", "')+'"');q.mode&&(I=q.mode),q.whitespace&&(B=q.whitespace),void 0!==q.tabWidth&&(M=q.tabWidth),q.skip&&(d=q.skip),q.skipScheme&&(g=q.skipScheme),q.lineBreak&&(u=q.lineBreak),q.lineBreakScheme&&(f=q.lineBreakScheme),q.respectLineBreaks&&(R=q.respectLineBreaks),void 0!==q.preservedLineIndent&&(m=q.preservedLineIndent),void 0!==q.wrapLineIndent&&(b=q.wrapLineIndent),q.wrapLineIndentBase&&(_=q.wrapLineIndentBase)}if(i.mode){if(!r[i.mode])throw new TypeError('mode must be one of "'+Object.keys(r).join('", "')+'"');I=i.mode}if(i.whitespace){if(!o[i.whitespace])throw new TypeError('whitespace must be one of "'+Object.keys(o).join('", "')+'"');B=i.whitespace}if(void 0!==i.tabWidth){if(!(parseInt(i.tabWidth,10)>=0))throw new TypeError("tabWidth must be a non-negative integer");M=parseInt(i.tabWidth,10)}if(L=new Array(M+1).join(" "),i.respectLineBreaks){if(!h[i.respectLineBreaks]&&!l.test(i.respectLineBreaks))throw new TypeError('respectLineBreaks must be one of "'+Object.keys(h).join('", "')+'", "m<num>", "s<num>"');R=i.respectLineBreaks}if("multi"===R)R="m",w=2;else if(!h[R]){var z=l.exec(R);R=z[1],w=parseInt(z[2],10)}if(void 0!==i.preservedLineIndent){if(!(parseInt(i.preservedLineIndent,10)>=0))throw new TypeError("preservedLineIndent must be a non-negative integer");m=parseInt(i.preservedLineIndent,10)}if(m>0&&(S=new Array(m+1).join(" ")),void 0!==i.wrapLineIndent){if(isNaN(parseInt(i.wrapLineIndent,10)))throw new TypeError("wrapLineIndent must be an integer");b=parseInt(i.wrapLineIndent,10)}if(i.wrapLineIndentBase&&(_=i.wrapLineIndentBase),_){if(void 0===b)throw new TypeError("wrapLineIndent must be specified when wrapLineIndentBase is specified");if(_ instanceof RegExp)x=_;else{if("string"!=typeof _)throw new TypeError("wrapLineIndentBase must be either a RegExp object or a string");x=new RegExp(p(_))}}else if(b>0)T=new Array(b+1).join(" ");else if(b<0)throw new TypeError("wrapLineIndent must be non-negative when a base is not specified");if(i.skipScheme){if(!a[i.skipScheme])throw new TypeError('skipScheme must be one of "'+Object.keys(a).join('", "')+'"');g=i.skipScheme}if(i.skip&&(d=i.skip),d)if(d instanceof RegExp)(y=d).global||(j="g",y.ignoreCase&&(j+="i"),y.multiline&&(j+="m"),y=new RegExp(y.source,j));else{if("string"!=typeof d)throw new TypeError("skip must be either a RegExp object or a string");y=new RegExp(p(d),"g")}if(!y&&g&&(y=a[g]),i.lineBreakScheme){if(!n[i.lineBreakScheme])throw new TypeError('lineBreakScheme must be one of "'+Object.keys(n).join('", "')+'"');f=i.lineBreakScheme}if(i.lineBreak&&(u=i.lineBreak),f&&(q=n[f])&&(v=q[0],k=q[1]),u)if(u instanceof Array&&(1===u.length?u=u[0]:u.length>=2&&(u[0]instanceof RegExp?(v=u[0],"string"==typeof u[1]&&(k=u[1])):u[1]instanceof RegExp?(v=u[1],"string"==typeof u[0]&&(k=u[0])):"string"==typeof u[0]&&"string"==typeof u[1]?(v=new RegExp(p(u[0]),"g"),k=u[1]):u=u[0])),"string"==typeof u)k=u,v||(v=new RegExp(p(u),"g"));else if(u instanceof RegExp)v=u;else if(!(u instanceof Array))throw new TypeError("lineBreak must be a RegExp object, a string, or an array consisted of a RegExp object and a string");v||(v=/\n/g,k="\n"),j="g",v.ignoreCase&&(j+="i"),v.multiline&&(j+="m"),E=new RegExp("\\s*(?:"+v.source+")(?:"+v.source+"|\\s)*",j),v.global||(v=new RegExp(v.source,j));var O="hard"===I?/\b/:/(\S+\s+)/,C=new Array(e+1).join(" "),U="default"===B||"collapse"===B,W="collapse"===B,N="line"===B,P="all"===B,G=/\t/g,H=/ +/g,K=/^\s+/,$=/\s+$/,F=/\S/,Q=/\s/,D=t-e;return function(s){var i;if(s=s.toString().replace(G,L),!k){if(v.lastIndex=0,!(i=v.exec(s)))throw new TypeError("Line break string for the output not specified");k=i[0]}var n,a,r,o,h,l,c,p,d,g=0;for(n=[],E.lastIndex=0,i=E.exec(s);i;){if(n.push(s.substring(g,i.index)),"none"!==R){for(r=[],o=0,v.lastIndex=0,a=v.exec(i[0]);a;)r.push(i[0].substring(o,a.index)),o=a.index+a[0].length,a=v.exec(i[0]);r.push(i[0].substring(o)),n.push({type:"break",breaks:r})}else h=W?" ":i[0].replace(v,""),n.push({type:"break",remaining:h});g=i.index+i[0].length,i=E.exec(s)}if(n.push(s.substring(g)),y)for(d=[],l=0;l<n.length;l++){var u=n[l];if("string"!=typeof u)d.push(u);else{for(g=0,y.lastIndex=0,i=y.exec(u);i;)d.push(u.substring(g,i.index)),d.push({type:"skip",value:i[0]}),g=i.index+i[0].length,i=y.exec(u);d.push(u.substring(g))}}else d=n;var f=[];for(l=0;l<d.length;l++){var m=d[l];if("string"!=typeof m)f.push(m);else{W&&(m=m.replace(H," "));var _=m.split(O),q=[];for(c=0;c<_.length;c++){var j=_[c];if("hard"===I)for(p=0;p<j.length;p+=D)q.push(j.slice(p,p+D));else q.push(j)}f=f.concat(q)}}var A,B=0,M=e+S.length,z=[C+S],V=0,J=!0,X=!0,Y=T;function Z(s){var i,n,a,r=z[B];if(P)M>t&&(V=V||t,a=r.length-(M-V),z[B]=r.substring(0,a)),V=0;else{for(i=r.length-1;i>=e&&" "===r[i];)i--;for(;i>=e&&Q.test(r[i]);)i--;++i!==r.length&&(z[B]=r.substring(0,i)),X&&J&&N&&M>t&&(a=r.length-(M-t))<i&&(a=i)}if(X&&(X=!1,x&&(i=z[B].substring(e).search(x),Y=i>=0&&i+b>0?new Array(i+b+1).join(" "):"")),a){for(;a+D<r.length;)P?(n=r.substring(a,a+D),z.push(C+Y+n)):z.push(C+Y),a+=D,B++;if(!s)return n=r.substring(a),Y+n;P?(n=r.substring(a),z.push(C+Y+n)):z.push(C+Y),B++}return""}for(l=0;l<f.length;l++){var ee=f[l];if(""!==ee)if("string"==typeof ee){for(var te;;){if(te=void 0,M+ee.length>t&&M+(te=ee.replace($,"")).length>t&&""!==te&&M>e){if(A=Z(!1),z.push(C+Y),B++,M=e+Y.length,A){z[B]+=A,M+=A.length,J=!0;continue}!U&&(!N||X&&J)||(ee=ee.replace(K,"")),J=!1}else J&&(U||N&&(!X||!J)?""!==(ee=ee.replace(K,""))&&(J=!1):F.test(ee)&&(J=!1));break}P&&te&&M+te.length>t&&(V=M+te.length),z[B]+=ee,M+=ee.length}else if("break"===ee.type)if("none"!==R){var se=ee.breaks,ie=se.length-1;if("s"===R){for(c=0;c<ie;c++)se[c+1].length<w?se[c+1]=W?" ":se[c]+se[c+1]:(P&&(z[B]+=se[c],M+=se[c].length),Z(!0),z.push(C+S),B++,M=e+S.length,X=J=!0);(!J||P||N&&X)&&((W||!J&&""===se[ie])&&(se[ie]=" "),z[B]+=se[ie],M+=se[ie].length)}else if("m"===R&&ie<w)(!J||P||N&&X)&&(W?ee=" ":(ee=se.join(""),J||""!==ee||(ee=" ")),z[B]+=ee,M+=ee.length);else if(U){for(Z(!0),c=0;c<ie;c++)z.push(C+S),B++;M=e+S.length,X=J=!0}else for((P||X&&J)&&(z[B]+=se[0],M+=se[0].length),c=0;c<ie;c++)Z(!0),z.push(C+S+se[c+1]),B++,M=e+S.length+se[c+1].length,X=J=!0}else(!J||P||N&&X)&&(ee=ee.remaining,(W||!J&&""===ee)&&(ee=" "),z[B]+=ee,M+=ee.length);else"skip"===ee.type&&(M>t&&(A=Z(!1),z.push(C+Y),B++,M=e+Y.length,A&&(z[B]+=A,M+=A.length),J=!0),z[B]+=ee.value)}return Z(!0),z.join(k)}};d.soft=d,d.hard=function(){var e=[].slice.call(arguments),t=e.length-1;return"object"==typeof e[t]?e[t].mode="hard":e.push({mode:"hard"}),d.apply(null,e)},d.wrap=function(e){var t=[].slice.call(arguments);return t.shift(),d.apply(null,t)(e)};var g=e(t.exports);var u=e(new class{grayscale(e){for(let t=0;t<e.data.length;t+=4){const s=.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2];e.data.fill(s,t,t+3)}return e}threshold(e,t){for(let s=0;s<e.data.length;s+=4){const i=.299*e.data[s]+.587*e.data[s+1]+.114*e.data[s+2]<t?0:255;e.data.fill(i,s,s+3)}return e}bayer(e,t){const s=[[15,135,45,165],[195,75,225,105],[60,180,30,150],[240,120,210,90]];for(let i=0;i<e.data.length;i+=4){const n=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2],a=i/4%e.width,r=Math.floor(i/4/e.width),o=Math.floor((n+s[a%4][r%4])/2)<t?0:255;e.data.fill(o,i,i+3)}return e}floydsteinberg(e){const t=e.width,s=new Uint8ClampedArray(e.width*e.height);for(let t=0,i=0;i<e.data.length;t++,i+=4)s[t]=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2];for(let i=0,n=0;n<e.data.length;i++,n+=4){const a=s[i]<129?0:255,r=Math.floor((s[i]-a)/16);e.data.fill(a,n,n+3),s[i+1]+=7*r,s[i+t-1]+=3*r,s[i+t]+=5*r,s[i+t+1]+=1*r}return e}atkinson(e){const t=e.width,s=new Uint8ClampedArray(e.width*e.height);for(let t=0,i=0;i<e.data.length;t++,i+=4)s[t]=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2];for(let i=0,n=0;n<e.data.length;i++,n+=4){const a=s[i]<129?0:255,r=Math.floor((s[i]-a)/8);e.data.fill(a,n,n+3),s[i+1]+=r,s[i+2]+=r,s[i+t-1]+=r,s[i+t]+=r,s[i+t+1]+=r,s[i+2*t]+=r}return e}});var f=e(new class{flatten(e,t){for(let s=0;s<e.data.length;s+=4){const i=e.data[s+3],n=255-i;e.data[s]=(i*e.data[s]+n*t[0])/255,e.data[s+1]=(i*e.data[s+1]+n*t[1])/255,e.data[s+2]=(i*e.data[s+2]+n*t[2])/255,e.data[s+3]=255}return e}});const w={cp437:{name:"USA, Standard Europe",languages:["en"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp720:{name:"Arabic",languages:["ar"],offset:128,chars:"éâàçêëèïîّْô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡ًٌٍَُِ≈°∙·√ⁿ²■ "},cp737:{name:"Greek",languages:["el"],offset:128,chars:"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ "},cp775:{name:"Baltic Rim",languages:["et","lt"],offset:128,chars:"ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£Ø×¤ĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’±“¾¶§÷„°∙·¹³²■ "},cp850:{name:"Multilingual",languages:["en"],offset:128,chars:"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´˝˛ˇ˘§÷¸°¨˙űŘř■ "},cp851:{name:"Greek",languages:["el"],offset:128,chars:"ÇüéâäàΆçêëèïîΈÄΉΊ ΌôöΎûùΏÖÜά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ´±υφχ§ψ¸°¨ωϋΰώ■ "},cp852:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´˝˛ˇ˘§÷¸°¨˙űŘř■ "},cp853:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàĉçêëèïîìÄĈÉċĊôöòûùİÖÜĝ£Ĝ×ĵáíóúñÑĞğĤĥ�½Ĵş«»░▒▓│┤ÁÂÀŞ╣║╗╝Żż┐└┴┬├─┼Ŝŝ╚╔╩╦╠═╬¤��ÊËÈıÍÎÏ┘┌█▄�Ì▀ÓßÔÒĠġµĦħÚÛÙŬŭ�´�ℓʼn˘§÷¸°¨˙�³²■ "},cp855:{name:"Cyrillic",languages:["bg"],offset:128,chars:"ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№ыЫзЗшШэЭщЩчЧ§■ "},cp857:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´±�¾¶§÷¸°¨·¹³²■ "},cp858:{name:"Euro",languages:["en"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ "},cp860:{name:"Portuguese",languages:["pt"],offset:128,chars:"ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp861:{name:"Icelandic",languages:["is"],offset:128,chars:"ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp862:{name:"Hebrew",languages:["he"],offset:128,chars:"אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp863:{name:"Canadian French",languages:["fr"],offset:128,chars:"ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp864:{name:"Arabic",languages:["ar"],offset:0,chars:"\0\b\t\n\v\f\r !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�"},cp865:{name:"Nordic",languages:["sv","dk"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp866:{name:"Cyrillic 2",languages:["ru"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ "},cp869:{name:"Greek",languages:["el"],offset:128,chars:"������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄±υφχ§ψ΅°¨ωϋΰώ■ "},cp874:{name:"Thai",languages:["th"],offset:128,chars:"€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"},cp1098:{name:"Farsi",languages:["fa"],offset:128,chars:" ،؛؟ًآﺂاﺎءأﺄؤﺋبﺑﭖﭘتﺗثﺛجﺟﭺﭼ×حﺣخﺧدذرزﮊسﺳشﺷصﺻ«»░▒▓│┤ضﺿﻁﻃ╣║╗╝¤ﻅ┐└┴┬├─┼ﻇع╚╔╩╦╠═╬ ﻊﻋﻌغﻎﻏﻐفﻓ┘┌█▄قﻗ▀ﮎﻛﮒﮔلﻟمﻣنﻧوهﻫﻬﮤﯼﯽﯾـ٠١٢٣٤٥٦٧٨٩■ "},cp1118:{name:"Lithuanian",languages:["lt"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀αβΓπΣσµτΦΘΩδ∞φε⋂≡±≥≤„“÷≈°∙˙√ⁿ²■ "},cp1119:{name:"Lithuanian",languages:["lt"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁё≥≤„“÷≈°∙·√ⁿ²■ "},cp1125:{name:"Ukrainian",languages:["uk"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ "},cp1162:{name:"Thai",languages:["th"],offset:128,chars:"€…‘’“”•–— กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"},cp2001:{name:"Lithuanian KBL or 771",languages:["lt"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█ĄąČčрстуфхцчшщъыьэюяĘęĖėĮįŠšŲųŪūŽž■ "},cp3001:{name:"Estonian 1 or 1116",languages:["et"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤šŠÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµžŽÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ "},cp3002:{name:"Estonian 2",languages:["et"],offset:128,chars:" ¡¢£¤¥¦§¨©ª«¬®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖרÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ"},cp3011:{name:"Latvian 1",languages:["lv"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤Ā╢ņ╕╣║╗╝╜╛┐└┴┬├─┼ā╟╚╔╩╦╠═╬╧Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀αßΓπΣσµτΦΘΩδ∞φε∩ĒēĢķĶļĻžŽ∙·√Ņš■ "},cp3012:{name:"Latvian 2 (modified 866)",languages:["lv"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤Ā╢ņ╕╣║╗╝Ō╛┐└┴┬├─┼ā╟╚╔╩╦╠═╬╧Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀рстуфхцчшщъыьэюяĒēĢķĶļĻžŽō·√Ņš■ "},cp3021:{name:"Bulgarian (MIK)",languages:["bg"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3041:{name:"Maltese ISO 646",languages:["mt"],offset:0,chars:"\0\b\t\n\v\f\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZġżħ^_ċabcdefghijklmnopqrstuvwxyzĠŻĦĊ"},cp3840:{name:"Russian (modified 866)",languages:["ru"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюя≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3841:{name:"Ghost",languages:["ru"],offset:128,chars:"ғәёіїјҝөўүӽӈҹҷє£ҒӘЁІЇЈҜӨЎҮӼӇҸҶЄЪ !\"#$%&'()*+,-./0123456789:;<=>?юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧ∅"},cp3843:{name:"Polish (Mazovia)",languages:["pl"],offset:128,chars:"ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖܢ٥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3844:{name:"Czech (Kamenický)",languages:["cz"],offset:128,chars:"ČüéďäĎŤčěĚĹÍľĺÄÁÉžŽôöÓůÚýÖÜŠĽÝŘťáíóúňŇŮÔšřŕŔ¼§«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3845:{name:"Hungarian (CWI-2)",languages:["hu"],offset:128,chars:"ÇüéâäàåçêëèïîÍÄÁÉæÆőöÓűÚŰÖÜ¢£¥₧ƒáíóúñÑªŐ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3846:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜ¢£¥ŞşáíóúñÑĞğ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3847:{name:"Brazil ABNT",languages:["pt"],offset:256,chars:""},cp3848:{name:"Brazil ABICOMP",languages:["pt"],offset:160,chars:" ÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖŒÙÚÛÜŸ¨£¦§°¡àáâãäçèéêëìíîïñòóôõöœùúûüÿߪº¿±"},iso88591:{name:"Latin 1",languages:["en"],offset:128,chars:" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},iso88592:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:" Ą˘Ł¤ĽŚ§¨ŠŞŤŹŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"},iso88597:{name:"Greek",languages:["el"],offset:128,chars:" ‘’£€₯¦§¨©ͺ«¬�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"},iso885915:{name:"Latin 9",languages:["fr"],offset:128,chars:" ¡¢£€¥Š§š©ª«¬®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},rk1048:{name:"Kazakh",languages:["kk"],offset:128,chars:"ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"},windows1250:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:"€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"},windows1251:{name:"Cyrillic",languages:["ru"],offset:128,chars:"ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"},windows1252:{name:"Latin",languages:["fr"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},windows1253:{name:"Greek",languages:["el"],offset:128,chars:"€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"},windows1254:{name:"Turkish",languages:["tr"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"},windows1255:{name:"Hebrew",languages:["he"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת���"},windows1256:{name:"Arabic",languages:["ar"],offset:128,chars:"€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œں ،¢£¤¥¦§¨©ھ«¬®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûüے"},windows1257:{name:"Baltic Rim",languages:["et","lt"],offset:128,chars:"€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙"},windows1258:{name:"Vietnamese",languages:["vi"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"}},m={en:"The quick brown fox jumps over the lazy dog.",jp:"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム",pt:"O próximo vôo à noite sobre o Atlântico, põe freqüentemente o único médico.",fr:"Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus en voyant leurs drôles d'œufs abîmés.",sv:"Flygande bäckasiner söka strax hwila på mjuka tuvor.",dk:"Quizdeltagerne spiste jordbær med fløde",el:"ξεσκεπάζω την ψυχοφθόρα βδελυγμία",tr:"Pijamalı hasta, yağız şoföre çabucak güvendi.",ru:"Съешь же ещё этих мягких французских булок да выпей чаю",hu:"Árvíztűrő tükörfúrógép",pl:"Pchnąć w tę łódź jeża lub ośm skrzyń fig",cz:"Mohu jíst sklo, neublíží mi.",ar:"أنا قادر على أكل الزجاج و هذا لا يؤلمني.",et:"Ma võin klaasi süüa, see ei tee mulle midagi.",lt:"Aš galiu valgyti stiklą ir jis manęs nežeidžia.",bg:"Мога да ям стъкло, то не ми вреди.",is:"Ég get etið gler án þess að meiða mig.",he:"אני יכול לאכול זכוכית וזה לא מזיק לי.",fa:".من می توانم بدونِ احساس درد شيشه بخورم",uk:"Я можу їсти скло, і воно мені не зашкодить.",vi:"Tôi có thể ăn thủy tinh mà không hại gì.",kk:"қазақша",lv:"Es varu ēst stiklu, tas man nekaitē.",mt:"Nista' niekol il-ħġieġ u ma jagħmilli xejn.",th:"ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ"};class b{static getEncodings(){return Object.keys(w)}static getTestStrings(e){return void 0!==w[e]&&void 0!==w[e].languages?w[e].languages.map((e=>({language:e,string:m[e]}))):[]}static supports(e){return void 0!==w[e]&&void 0!==w[e].chars}static encode(e,t){const s=new Uint8Array(e.length);let i="\0".repeat(128),n=128;void 0!==w[t]&&void 0!==w[t].chars&&(i=w[t].chars,n=w[t].offset);for(let t=0;t<e.length;t++){const a=e.codePointAt(t);if(a<128)s[t]=a;else{const r=i.indexOf(e[t]);-1!==r?s[t]=n+r:a<256&&(a<n||a>=n+i.length)?s[t]=a:s[t]=63}}return s}static autoEncode(e,t){const s=[];let i,n=-1;for(let a=0;a<e.length;a++){const r=e.codePointAt(a);let o,h=0;if(r<128&&(o=i||t[0],h=r),!o&&i){const t=w[i].chars.indexOf(e[a]);-1!==t&&(o=i,h=w[i].offset+t)}if(!o)for(let s=0;s<t.length;s++){const i=w[t[s]].chars.indexOf(e[a]);if(-1!==i){o=t[s],h=w[t[s]].offset+i;break}}o||(o=i||t[0],h=63),i!=o&&(i&&(s[n].bytes=new Uint8Array(s[n].bytes)),n++,s[n]={codepage:o,bytes:[]},i=o),s[n].bytes.push(h)}return i&&(s[n].bytes=new Uint8Array(s[n].bytes)),s}}const _={epson:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp851:11,cp853:12,cp857:13,cp737:14,iso88597:15,windows1252:16,cp866:17,cp852:18,cp858:19,cp720:32,cp775:33,cp855:34,cp861:35,cp862:36,cp864:37,cp869:38,iso88592:39,iso885915:40,cp1098:41,cp1118:42,cp1119:43,cp1125:44,windows1250:45,windows1251:46,windows1253:47,windows1254:48,windows1255:49,windows1256:50,windows1257:51,windows1258:52,rk1048:53},zjiang:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,windows1252:16,cp866:17,cp852:18,cp858:19,windows1255:32,cp861:56,cp855:60,cp857:61,cp862:62,cp864:63,cp737:64,cp851:65,cp869:66,cp1119:68,cp1118:69,windows1250:72,windows1251:73,cp3840:74,cp3843:76,cp3844:77,cp3845:78,cp3846:79,cp3847:80,cp3848:81,cp2001:83,cp3001:84,cp3002:85,cp3011:86,cp3012:87,cp3021:88,cp3041:89,windows1253:90,windows1254:91,windows1256:92,cp720:93,windows1258:94,cp775:95},bixolon:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp851:11,cp858:19},star:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,windows1252:16,cp866:17,cp852:18,cp858:19},citizen:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp852:18,cp866:17,cp857:8,windows1252:16,cp858:19,cp864:40},legacy:{cp437:0,cp737:64,cp850:2,cp775:95,cp852:18,cp855:60,cp857:61,cp858:19,cp860:3,cp861:56,cp862:62,cp863:4,cp864:28,cp865:5,cp866:17,cp869:66,cp936:255,cp949:253,cp950:254,cp1252:16,iso88596:22,shiftjis:252,windows874:30,windows1250:72,windows1251:73,windows1252:71,windows1253:90,windows1254:91,windows1255:32,windows1256:92,windows1257:25,windows1258:94}};class y{constructor(e){this._reset(e)}_reset(e){this._options=Object.assign({width:null,embedded:!1,wordWrap:!0,imageMode:"column",codepageMapping:"epson",codepageCandidates:["cp437","cp858","cp860","cp861","cp863","cp865","cp852","cp857","cp855","cp866","cp869"]},e),this._embedded=this._options.width&&this._options.embedded,this._buffer=[],this._queued=[],this._cursor=0,this._codepage="ascii",this._state={codepage:0,align:"left",bold:!1,italic:!1,underline:!1,invert:!1,width:1,height:1}}_encode(e){if("auto"!=this._codepage)return b.encode(e,this._codepage);let t;t="string"==typeof this._options.codepageMapping?_[this._options.codepageMapping]:this._options.codepageMapping;const s=b.autoEncode(e,this._options.codepageCandidates);let i=0;for(let e=0;e<s.length;e++)i+=3+s[e].bytes.byteLength;const n=new Uint8Array(i);let a=0;for(let e=0;e<s.length;e++)n.set([27,116,t[s[e].codepage]],a),n.set(s[e].bytes,a+3),a+=3+s[e].bytes.byteLength,this._state.codepage=t[s[e].codepage];return n}_queue(e){e.forEach((e=>this._queued.push(e)))}_flush(){if(this._embedded){let e=this._options.width-this._cursor;if("left"==this._state.align&&this._queued.push(new Array(e).fill(32)),"center"==this._state.align){const t=e%2;e>>=1,e>0&&this._queued.push(new Array(e).fill(32)),e+t>0&&this._queued.unshift(new Array(e+t).fill(32))}"right"==this._state.align&&this._queued.unshift(new Array(e).fill(32))}this._buffer=this._buffer.concat(this._queued),this._queued=[],this._cursor=0}_wrap(e,t){if(t||this._options.wordWrap&&this._options.width){const s="-".repeat(this._cursor);return g(t||this._options.width,{lineBreak:"\n",whitespace:"all"})(s+e).substring(this._cursor).split("\n")}return[e]}_restoreState(){this.bold(this._state.bold),this.italic(this._state.italic),this.underline(this._state.underline),this.invert(this._state.invert),this._queue([27,116,this._state.codepage])}_getCodepageIdentifier(e){let t;return t="string"==typeof this._options.codepageMapping?_[this._options.codepageMapping]:this._options.codepageMapping,t[e]}initialize(){return this._queue([27,64]),this._flush(),this}codepage(e){if("auto"===e)return this._codepage=e,this;if(!b.supports(e))throw new Error("Unknown codepage");let t;if(t="string"==typeof this._options.codepageMapping?_[this._options.codepageMapping]:this._options.codepageMapping,void 0===t[e])throw new Error("Codepage not supported by printer");return this._codepage=e,this._state.codepage=t[e],this._queue([27,116,t[e]]),this}text(e,t){const s=this._wrap(e,t);for(let e=0;e<s.length;e++){const t=this._encode(s[e]);this._queue([t]),this._cursor+=s[e].length*this._state.width,this._options.width&&!this._embedded&&(this._cursor=this._cursor%this._options.width),e<s.length-1&&this.newline()}return this}newline(){return this._flush(),this._queue([10,13]),this._embedded&&this._restoreState(),this}line(e,t){return this.text(e,t),this.newline(),this}underline(e){return void 0===e&&(e=!this._state.underline),this._state.underline=e,this._queue([27,45,Number(e)]),this}italic(e){return void 0===e&&(e=!this._state.italic),this._state.italic=e,this._queue([27,52,Number(e)]),this}bold(e){return void 0===e&&(e=!this._state.bold),this._state.bold=e,this._queue([27,69,Number(e)]),this}width(e){if(void 0===e&&(e=1),"number"!=typeof e)throw new Error("Width must be a number");if(e<1||e>8)throw new Error("Width must be between 1 and 8");return this._state.width=e,this._queue([29,33,this._state.height-1|this._state.width-1<<4]),this}height(e){if(void 0===e&&(e=1),"number"!=typeof e)throw new Error("Height must be a number");if(e<1||e>8)throw new Error("Height must be between 1 and 8");return this._state.height=e,this._queue([29,33,this._state.height-1|this._state.width-1<<4]),this}invert(e){return void 0===e&&(e=!this._state.invert),this._state.invert=e,this._queue([29,66,Number(e)]),this}size(e){return e="small"===e?1:0,this._queue([27,77,e]),this}align(e){const t={left:0,center:1,right:2};if(!(e in t))throw new Error("Unknown alignment");return this._state.align=e,this._embedded||this._queue([27,97,t[e]]),this}table(e,t){0!=this._cursor&&this.newline();for(let s=0;s<t.length;s++){const i=[];let n=0;for(let a=0;a<e.length;a++){const r=[];if("string"==typeof t[s][a]){const i=g(e[a].width,{lineBreak:"\n"})(t[s][a]).split("\n");for(let t=0;t<i.length;t++)"right"==e[a].align?r[t]=this._encode(i[t].padStart(e[a].width)):r[t]=this._encode(i[t].padEnd(e[a].width))}if("function"==typeof t[s][a]){const i=new y(Object.assign({},this._options,{width:e[a].width,embedded:!0}));i._codepage=this._codepage,i.align(e[a].align),t[s][a](i);const n=i.encode();let o=[];for(let e=0;e<n.byteLength;e++)e<n.byteLength-1&&10===n[e]&&13===n[e+1]?(r.push(o),o=[],e++):o.push(n[e]);o.length&&r.push(o)}n=Math.max(n,r.length),i[a]=r}for(let t=0;t<e.length;t++)if(i[t].length<n)for(let s=i[t].length;s<n;s++){let s="top";void 0!==e[t].verticalAlign&&(s=e[t].verticalAlign),"bottom"==s?i[t].unshift(new Array(e[t].width).fill(32)):i[t].push(new Array(e[t].width).fill(32))}for(let t=0;t<n;t++){for(let s=0;s<e.length;s++)void 0!==e[s].marginLeft&&this.raw(new Array(e[s].marginLeft).fill(32)),this.raw(i[s][t]),void 0!==e[s].marginRight&&this.raw(new Array(e[s].marginRight).fill(32));this.newline()}}return this}rule(e){return e=Object.assign({style:"single",width:this._options.width||10},e||{}),this._queue([27,116,this._getCodepageIdentifier("cp437"),new Array(e.width).fill("double"===e.style?205:196)]),this._queue([27,116,this._state.codepage]),this.newline(),this}box(e,t){let s;s="double"==(e=Object.assign({style:"single",width:this._options.width||30,marginLeft:0,marginRight:0,paddingLeft:0,paddingRight:0},e||{})).style?[201,187,200,188,205,186]:[218,191,192,217,196,179],0!=this._cursor&&this.newline(),this._restoreState(),this._queue([27,116,this._getCodepageIdentifier("cp437")]),this._queue([new Array(e.marginLeft).fill(32),s[0],new Array(e.width-2).fill(s[4]),s[1],new Array(e.marginRight).fill(32)]),this.newline();const i=[];if("string"==typeof t){const s=g(e.width-2-e.paddingLeft-e.paddingRight,{lineBreak:"\n"})(t).split("\n");for(let t=0;t<s.length;t++)"right"==e.align?i[t]=this._encode(s[t].padStart(e.width-2-e.paddingLeft-e.paddingRight)):i[t]=this._encode(s[t].padEnd(e.width-2-e.paddingLeft-e.paddingRight))}if("function"==typeof t){const s=new y(Object.assign({},this._options,{width:e.width-2-e.paddingLeft-e.paddingRight,embedded:!0}));s._codepage=this._codepage,s.align(e.align),t(s);const n=s.encode();let a=[];for(let e=0;e<n.byteLength;e++)e<n.byteLength-1&&10===n[e]&&13===n[e+1]?(i.push(a),a=[],e++):a.push(n[e]);a.length&&i.push(a)}for(let t=0;t<i.length;t++)this._queue([new Array(e.marginLeft).fill(32),s[5],new Array(e.paddingLeft).fill(32)]),this._queue([i[t]]),this._restoreState(),this._queue([27,116,this._getCodepageIdentifier("cp437")]),this._queue([new Array(e.paddingRight).fill(32),s[5],new Array(e.marginRight).fill(32)]),this.newline();return this._queue([new Array(e.marginLeft).fill(32),s[2],new Array(e.width-2).fill(s[4]),s[3],new Array(e.marginRight).fill(32)]),this._restoreState(),this.newline(),this}barcode(e,t,s){if(this._embedded)throw new Error("Barcodes are not supported in table cells or boxes");const i={upca:0,upce:1,ean13:2,ean8:3,code39:4,coda39:4,itf:5,codabar:6,code93:72,code128:73,"gs1-128":80,"gs1-databar-omni":81,"gs1-databar-truncated":82,"gs1-databar-limited":83,"gs1-databar-expanded":84,"code128-auto":85};if(!(t in i))throw new Error("Symbology not supported by printer");{const n=b.encode(e,"ascii");0!=this._cursor&&this.newline(),this._queue([29,104,s,29,119,"code39"===t?2:3]),"code128"==t&&123!==n[0]?this._queue([29,107,i[t],n.length+2,123,66,n]):i[t]>64?this._queue([29,107,i[t],n.length,n]):this._queue([29,107,i[t],n,0])}return this._flush(),this}qrcode(e,t,s,i){if(this._embedded)throw new Error("QR codes are not supported in table cells or boxes");this._queue([10]);const n={1:49,2:50};if(void 0===t&&(t=2),!(t in n))throw new Error("Model must be 1 or 2");if(this._queue([29,40,107,4,0,49,65,n[t],0]),void 0===s&&(s=6),"number"!=typeof s)throw new Error("Size must be a number");if(s<1||s>8)throw new Error("Size must be between 1 and 8");this._queue([29,40,107,3,0,49,67,s]);const a={l:48,m:49,q:50,h:51};if(void 0===i&&(i="m"),!(i in a))throw new Error("Error level must be l, m, q or h");this._queue([29,40,107,3,0,49,69,a[i]]);const r=b.encode(e,"iso88591"),o=r.length+3;return this._queue([29,40,107,o%255,o/255,49,80,48,r]),this._queue([29,40,107,3,0,49,81,48]),this._flush(),this}image(e,t,s,i,n){if(this._embedded)throw new Error("Images are not supported in table cells or boxes");if(t%8!=0)throw new Error("Width must be a multiple of 8");if(s%8!=0)throw new Error("Height must be a multiple of 8");void 0===i&&(i="threshold"),void 0===n&&(n=128);const a=function(e,t){return Object.assign(document.createElement("canvas"),{width:e,height:t})}(t,s),r=a.getContext("2d");r.drawImage(e,0,0,t,s);let o=r.getImageData(0,0,t,s);switch(o=f.flatten(o,[255,255,255]),i){case"threshold":o=u.threshold(o,n);break;case"bayer":o=u.bayer(o,n);break;case"floydsteinberg":o=u.floydsteinberg(o);break;case"atkinson":o=u.atkinson(o)}const h=(e,i)=>e<t&&i<s?o.data[4*(t*i+e)]>0?0:1:0,l=(e,t)=>{const s=new Uint8Array(e*t>>3);for(let i=0;i<t;i++)for(let t=0;t<e;t+=8)for(let n=0;n<8;n++)s[i*(e>>3)+(t>>3)]|=h(t+n,i)<<7-n;return s};return 0!=this._cursor&&this.newline(),"column"==this._options.imageMode&&(this._queue([27,51,36]),((e,t)=>{const s=[];for(let i=0;i<Math.ceil(t/24);i++){const t=new Uint8Array(3*e);for(let s=0;s<e;s++)for(let e=0;e<3;e++)for(let n=0;n<8;n++)t[3*s+e]|=h(s,24*i+n+8*e)<<7-n;s.push(t)}return s})(t,s).forEach((e=>{this._queue([27,42,33,255&t,t>>8&255,e,10])})),this._queue([27,50])),"raster"==this._options.imageMode&&this._queue([29,118,48,0,t>>3&255,t>>3>>8&255,255&s,s>>8&255,l(t,s)]),this._flush(),this}cut(e){if(this._embedded)throw new Error("Cut is not supported in table cells or boxes");let t=0;return"partial"==e&&(t=1),this._queue([29,86,t]),this}pulse(e,t,s){if(this._embedded)throw new Error("Pulse is not supported in table cells or boxes");return void 0===e&&(e=0),void 0===t&&(t=100),void 0===s&&(s=500),t=Math.min(500,Math.round(t/2)),s=Math.min(500,Math.round(s/2)),this._queue([27,112,e?1:0,255&t,255&s]),this}raw(e){return this._queue(e),this}encode(){this._flush();let e=0;this._buffer.forEach((t=>{"number"==typeof t?e++:e+=t.length}));const t=new Uint8Array(e);let s=0;return this._buffer.forEach((e=>{"number"==typeof e?(t[s]=e,s++):(t.set(e,s),s+=e.length)})),this._reset(),t}}return y})); |
+1
-1
| MIT License | ||
| Copyright (c) 2019 Anson Tio | ||
| Copyright (c) 2024 Ryan Huxley | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
+28
-18
| { | ||
| "name": "@mineminemine/esc-pos-encoder-ionic", | ||
| "version": "2.0.3", | ||
| "version": "3.0.0", | ||
| "description": "Create a set of commands that can be send to any receipt printer that supports ESC/POS", | ||
| "main": "src/esc-pos-encoder.js", | ||
| "type": "module", | ||
| "exports": { | ||
| "browser": { | ||
| "import": "./dist/esc-pos-encoder.esm.js", | ||
| "require": "./dist/esc-pos-encoder.umd.js", | ||
| "script": "./dist/esc-pos-encoder.umd.js" | ||
| }, | ||
| "import": "./dist/esc-pos-encoder.mjs", | ||
| "require": "./dist/esc-pos-encoder.cjs" | ||
| }, | ||
| "main": "dist/esc-pos-encoder.cjs", | ||
| "module": "dist/esc-pos-encoder.mjs", | ||
| "scripts": { | ||
| "bundle": "browserify src/esc-pos-encoder.js --standalone EscPosEncoder -o dist/esc-pos-encoder.js", | ||
| "uglify": "uglifyjs dist/esc-pos-encoder.js -cm --overwrite -o dist/esc-pos-encoder.js", | ||
| "build": "npm run bundle && npm run uglify", | ||
| "build": "rollup -c", | ||
| "lint": "eslint --fix src/esc-pos-encoder.js", | ||
@@ -26,3 +35,4 @@ "mocha": "mocha test/", | ||
| "ionic5", | ||
| "ionic6" | ||
| "ionic6", | ||
| "ionic7" | ||
| ], | ||
@@ -36,21 +46,21 @@ "author": "Ryan Huxley", | ||
| "devDependencies": { | ||
| "browserify": "^17.0.0", | ||
| "buffer-to-uint8array": "^1.1.0", | ||
| "chai": "^4.3.4", | ||
| "eslint": "^7.31.0", | ||
| "@rollup/plugin-commonjs": "^24.1.0", | ||
| "@rollup/plugin-node-resolve": "^15.0.2", | ||
| "@rollup/plugin-terser": "^0.4.1", | ||
| "chai": "^4.3.7", | ||
| "eslint": "^8.39.0", | ||
| "eslint-config-google": "^0.14.0", | ||
| "iconv-lite": "^0.6.3", | ||
| "mocha": "^9.0.2", | ||
| "uglify-es": "^3.3.9" | ||
| "mocha": "^10.2.0", | ||
| "rollup": "^3.20.7" | ||
| }, | ||
| "dependencies": { | ||
| "canvas": "^2.8.0", | ||
| "canvas": "^2.11.2", | ||
| "canvas-dither": "^1.0.1", | ||
| "canvas-flatten": "^1.0.1", | ||
| "codepage-encoder": "^1.0.0", | ||
| "codepage-encoder": "^2.0.4", | ||
| "linewrap": "^0.2.1" | ||
| }, | ||
| "directories": { | ||
| "test": "test" | ||
| } | ||
| "files": [ | ||
| "dist" | ||
| ] | ||
| } |
+137
-69
| # esc-pos-encoder-ionic | ||
| This is a fork of [EscPosEncoder](https://github.com/Ans0n-Ti0/EscPosEncoder) by Anson Tio that is intended to work with Ionic. I have only updated his fork to match the latest [EscPosEncoder](https://github.com/NielsLeenheer/EscPosEncoder) by NielsLeenheer. | ||
| Create a set of commands that can be send to any receipt printer that supports ESC/POS. | ||
| This is ionic friendly, which mean you can use this for your ionic project too! | ||
| Before you use this library, you should also consider [ThermalPrinterEncoder](https://github.com/NielsLeenheer/ThermalPrinterEncoder), which is based on [EscPosEncoder](https://github.com/NielsLeenheer/EscPosEncoder), but also adds support for the StarPRNT language by using [StarPrntEncoder](https://github.com/NielsLeenheer/StarPrntEncoder). The API of ThermalPrinter is identical to this one and you should just be able to swap it out without any further changes. | ||
| ## Usage | ||
@@ -12,5 +15,5 @@ | ||
| Then, require the package and use it like so: | ||
| If you prefer ES6 modules, then import `EscPosEncoder` from `esc-pos-encoder` and use it like so: | ||
| let EscPosEncoder = require('esc-pos-encoder'); | ||
| import EscPosEncoder from '@mineminemine/esc-pos-encoder-ionic'; | ||
@@ -26,19 +29,39 @@ let encoder = new EscPosEncoder(); | ||
| ## Commands | ||
| Alternatively you could use the CommonJS way of doing things and require the package: | ||
| You can reuse the instantiated `EscPosEncoder` class to generate multiple commands or sets of commands for the same printer. It will remember settings like code page, so you don't have to specify that on subsequent use. That does rely on that previous commands were actually send to the printer. | ||
| let EscPosEncoder = require('@mineminemine/esc-pos-encoder-ionic'); | ||
| All commands can be chained, except for `encode()` which will return the result as an Uint8Array which contains all the bytes that need to be send to the printer. | ||
| let encoder = new EscPosEncoder(); | ||
| ## Options | ||
| ## Usage (Ionic) | ||
| When you create the `EscPosEncoder` object you can specify a number of options to help with the library with generating receipts. | ||
| On the page that you want to have the encoder, type this | ||
| ### Width | ||
| import EscPosEncoder from '@mineminemine/esc-pos-encoder-ionic'; | ||
| Then inside the class method, you can access it by using: | ||
| To set the width of the paper you can use the `width` property. This is option, as text automatically wraps to a new line if the edge of the paper is reached, but if you want to use word wrap, you need to specify this. | ||
| const encoder = new EscPosEncoder(); | ||
| let encoder = new EscPosEncoder({ | ||
| width: 42 | ||
| }); | ||
| If you use 57mm wide paper, it allows you to print up to 32 or 35 characters horizontally, depending on the resolution of the printer. | ||
| If you use 80mm wide paper, it allows you to print up to 42 or 48 characters horizontally, depending on the resolution of the printer. | ||
| ## Word wrap | ||
| If you want text to automatically word wrap at the edge of the paper you can turn on `wordWrap`. If you use this option you also must specify a paper width using the `width` property. | ||
| let encoder = new EscPosEncoder({ | ||
| width: 48, | ||
| wordWrap: true | ||
| }); | ||
| ## Commands | ||
| You can reuse the instantiated `EscPosEncoder` class to generate multiple commands or sets of commands for the same printer. It will remember settings like code page, so you don't have to specify that on subsequent use. That does rely on that previous commands were actually send to the printer. | ||
| All commands can be chained, except for `encode()` which will return the result as an Uint8Array which contains all the bytes that need to be send to the printer. | ||
| The following commands are available: | ||
@@ -56,5 +79,5 @@ | ||
| Set the code page of the printer. Receipt printers don't support UTF-8 or any other unicode encoding, instead the rely on legacy code pages. | ||
| Set the code page of the printer. Receipt printers don't support UTF-8 or any other unicode encoding, instead the rely on legacy code pages. | ||
| If you specify the code page, it will send a command to the printer to enable that particular code page and from then on it will automatically encode all text string to that code page. | ||
| If you specify the code page, it will send a command to the printer to enable that particular code page and from then on it will automatically encode all text string to that code page. | ||
@@ -74,5 +97,5 @@ If you don't specify a code page, it will assume you want to print only ASCII characters and strip out any others. | ||
| Support for one specific code pages is not only dependant on this library, even more important is that the printer understands it. And support for code pages depend on manufacturer and model. Some only support a few, some support most of these. There are probably no printers that support all of them. | ||
| Support for one specific code pages is not only dependant on this library, even more important is that the printer understands it. And support for code pages depend on manufacturer and model. Some only support a few, some support most of these. There are probably no printers that support all of them. | ||
| Before choosing a code page, check the technical manual of your printer which codepages are supported. If your printer does not support a code page that you need, you are out of luck and nothing this library does can help you solve this problem. | ||
| Before choosing a code page, check the technical manual of your printer which codepages are supported. If your printer does not support a code page that you need, you are out of luck and nothing this library does can help you solve this problem. | ||
@@ -90,4 +113,4 @@ #### Advanced text compositing | ||
| let encoder = new EscPosEncoder({ | ||
| codepageMapping: 'bixolon' | ||
| let encoder = new EscPosEncoder({ | ||
| codepageMapping: 'bixolon' | ||
| }); | ||
@@ -97,3 +120,3 @@ | ||
| let encoder = new EscPosEncoder({ | ||
| let encoder = new EscPosEncoder({ | ||
| codepageMapping: { | ||
@@ -107,11 +130,10 @@ 'cp437': 0x00, | ||
| 'cp858': 0x13, | ||
| } | ||
| } | ||
| }); | ||
| Each property name must be one of the code pages supported by this library and the value is the number which is used for that code page on your printer. | ||
| Each property name must be one of the code pages supported by this library and the value is the number which is used for that code page on your printer. | ||
| #### Auto encoding | ||
| It is also possible to enable auto encoding of code pages. The library will then automatically switch between code pages depending on the text that you want to print. | ||
| It is also possible to enable auto encoding of code pages. The library will then automatically switch between code pages depending on the text that you want to print. | ||
@@ -134,3 +156,3 @@ let result = encoder | ||
| let encoder = new EscPosEncoder({ | ||
| let encoder = new EscPosEncoder({ | ||
| codepageCandidates: [ | ||
@@ -142,3 +164,2 @@ 'cp437', 'cp858', 'cp860', 'cp861', 'cp863', 'cp865', | ||
| ### Text | ||
@@ -192,3 +213,3 @@ | ||
| Change the text style to underline. | ||
| Change the text style to underline. | ||
@@ -213,3 +234,3 @@ let result = encoder | ||
| Change the text style to bold. | ||
| Change the text style to bold. | ||
@@ -234,3 +255,3 @@ let result = encoder | ||
| Change the text style to italic. | ||
| Change the text style to italic. | ||
@@ -253,7 +274,7 @@ let result = encoder | ||
| Note: this text style is not supported by most receipt printers. | ||
| Note: this text style is not supported by most receipt printers. | ||
| ### Invert | ||
| Change the style to white text on a black background. | ||
| Change the style to white text on a black background. | ||
@@ -334,9 +355,8 @@ let result = encoder | ||
| .width(2) | ||
| .width(2) | ||
| .height(2) | ||
| .line('This text is twice as large as normal text') | ||
| .width(1) | ||
| .height(1) | ||
| .height(1) | ||
| .encode() | ||
| ### Table | ||
@@ -351,3 +371,3 @@ | ||
| { width: 10, align: 'right' } | ||
| ], | ||
| ], | ||
| [ | ||
@@ -362,13 +382,59 @@ [ 'Item 1', '€ 10,00' ], | ||
| ] | ||
| ) | ||
| ) | ||
| .encode() | ||
| The table function takes two parameters. | ||
| The first parameter is an array of column definitions. Each column can have the folowing properties: | ||
| - `width`: determines the width of the column. | ||
| - `marginLeft` and `marginRight`: set a margin to the left and right of the column. | ||
| - `align`: sets the horizontal alignment of the text in the column and can either be `left` or `right`. | ||
| - `verticalAlign`: sets the vertical alignment of the text in the column and can either be `top` or `bottom`. | ||
| The second parameter contains the data and is an array that contains each row. There can be as many rows as you would like. | ||
| Each row is an array with a value for each cell. The number of cells in each row should be equal to the number of columns you defined previously. | ||
| [ | ||
| /* Row one, with two columns */ | ||
| [ 'Cell one', 'Cell two' ], | ||
| /* Row two, with two columns */ | ||
| [ 'Cell three', 'Cell four' ] | ||
| ] | ||
| The value can either be a string or a callback function. | ||
| If you want to style text inside of a cell, can use the callback function instead. The first parameter of the called function contains the encoder object which you can use to chain additional commands. | ||
| [ | ||
| /* Row one, with two columns */ | ||
| [ | ||
| 'Cell one', | ||
| (encoder) => encoder.bold().text('Cell two').bold() | ||
| ], | ||
| ] | ||
| ### Box | ||
| Insert a bordered box. The content of the box can be a string, or a callback function. | ||
| Insert a bordered box. | ||
| The first parameter is an object with additional configuration options. | ||
| - `style`: The style of the border, either `single` or `double` | ||
| - `width`: The width of the box, by default the width of the paper | ||
| - `marginLeft`: Space between the left border and the left edge | ||
| - `marginRight`: Space between the right border and the right edge | ||
| - `paddingLeft`: Space between the contents and the left border of the box | ||
| - `paddingRight`: Space between the contents and the right border of the box | ||
| - `align`: The alignment of the text within the box, can be `left` or `right`. | ||
| The second parameter is the content of the box and it can be a string, or a callback function. | ||
| For example: | ||
| let result = encoder | ||
| .box( | ||
| { width: 30, align: 'right', style: 'double', marginLeft: 10 }, | ||
| { width: 30, align: 'right', style: 'double', marginLeft: 10 }, | ||
| 'The quick brown fox jumps over the lazy dog | ||
@@ -378,3 +444,2 @@ ) | ||
| ### Rule | ||
@@ -384,7 +449,13 @@ | ||
| The first parameters is an object with additional styling options: | ||
| - `style`: The style of the line, either `single` or `double` | ||
| - `width`: The width of the line, by default the width of the paper | ||
| For example: | ||
| let result = encoder | ||
| .rule({ style: 'double' }) | ||
| .rule({ style: 'double' }) | ||
| .encode() | ||
| ### Barcode | ||
@@ -398,3 +469,3 @@ | ||
| In general the printer will automatically calculate the checksum if one is not provided. If one is provided in the data, it will not check the checksum. If you provide the checksum yourself and it is not correctly calculated, the behaviour is not defined. It may calculate the correct checksum use that instead or print an invalid barcode. | ||
| In general the printer will automatically calculate the checksum if one is not provided. If one is provided in the data, it will not check the checksum. If you provide the checksum yourself and it is not correctly calculated, the behaviour is not defined. It may calculate the correct checksum use that instead or print an invalid barcode. | ||
@@ -417,18 +488,18 @@ For example with the checksum provided in the data: | ||
| | Symbology | Length | Characters | | ||
| |-|-|-| | ||
| | upca | 11 - 12 | 0 - 9 | | ||
| | ean8 | 7 - 8 | 0 - 9 | | ||
| | ean13 | 12 - 13 | 0 - 9 | | ||
| | code39 | >= 1 | 0 - 9, A - Z, space, or $ % * + - . / | | ||
| | itf | >= 2 (even) | 0 - 9 | | ||
| | codabar | >= 2 | 0 - 9, A - D, a - d, or $ + − . / : | | ||
| | code93 | 1 - 255 | ASCII character (0 - 127) | | ||
| | code128 | 1 - 253 | ASCII character (32 - 127) | | ||
| | Symbology | Length | Characters | | ||
| | --------- | ----------- | -------------------------------------- | | ||
| | upca | 11 - 12 | 0 - 9 | | ||
| | ean8 | 7 - 8 | 0 - 9 | | ||
| | ean13 | 12 - 13 | 0 - 9 | | ||
| | code39 | >= 1 | 0 - 9, A - Z, space, or $ % \* + - . / | | ||
| | itf | >= 2 (even) | 0 - 9 | | ||
| | codabar | >= 2 | 0 - 9, A - D, a - d, or $ + − . / : | | ||
| | code93 | 1 - 255 | ASCII character (0 - 127) | | ||
| | code128 | 1 - 253 | ASCII character (32 - 127) | | ||
| The Code 128 symbology specifies three different code sets which contain different characters. For example: CODE A contains ASCII control characters, special characters, digits and uppercase letters. CODE B contains special characters, digits, uppercase letters and lowercase letters. CODE C prints 2 digits numbers that correspond to the ASCII value of the letter. | ||
| The Code 128 symbology specifies three different code sets which contain different characters. For example: CODE A contains ASCII control characters, special characters, digits and uppercase letters. CODE B contains special characters, digits, uppercase letters and lowercase letters. CODE C prints 2 digits numbers that correspond to the ASCII value of the letter. | ||
| By default Code 128 uses CODE B. It is possible to use a different code set, by using the code set selector character { followed by the uppercase letter of the character set. | ||
| For example with the default CODE B set: | ||
| For example with the default CODE B set: | ||
@@ -457,4 +528,2 @@ let result = encoder | ||
| ### Qrcode | ||
@@ -470,5 +539,5 @@ | ||
| - *model* - a number that can be 1 for Model 1 and 2 for Model 2 | ||
| - *size* - a number that can be between 1 and 8 for determining the size of the QR code | ||
| - *errorlevel* - a string that can be either 'l', 'm', 'q' or 'h'. | ||
| - _model_ - a number that can be 1 for Model 1 and 2 for Model 2 | ||
| - _size_ - a number that can be between 1 and 8 for determining the size of the QR code | ||
| - _errorlevel_ - a string that can be either 'l', 'm', 'q' or 'h'. | ||
@@ -481,3 +550,2 @@ For example: | ||
| ### Image | ||
@@ -487,3 +555,3 @@ | ||
| The first parameter is the image itself. When running in the browser it can be any element that can be drawn onto a canvas, like an img, svg, canvas and video elements. When on Node it can be a Canvas provided by the `canvas` package. | ||
| The first parameter is the image itself. When running in the browser it can be any element that can be drawn onto a canvas, like an img, svg, canvas and video elements. When on Node it can be a Canvas provided by the `canvas` package. | ||
@@ -500,3 +568,3 @@ The second parameter is the width of the image on the paper receipt in pixels. It must be a multiple of 8. | ||
| img.src = 'https://...'; | ||
| img.onload = function() { | ||
@@ -514,4 +582,4 @@ let result = encoder | ||
| let encoder = new EscPosEncoder({ | ||
| imageMode: 'raster' | ||
| let encoder = new EscPosEncoder({ | ||
| imageMode: 'raster' | ||
| }); | ||
@@ -523,3 +591,3 @@ | ||
| Cut the paper. Optionally a parameter can be specified which can be either be "partial" or "full". If not specified, a full cut will be used. | ||
| Cut the paper. Optionally a parameter can be specified which can be either be "partial" or "full". If not specified, a full cut will be used. | ||
@@ -530,7 +598,7 @@ let result = encoder | ||
| Note: Not all printer models support cutting paper. And even if they do, they might not support both types of cuts. | ||
| _Note: Not all printer models support cutting paper. And even if they do, they might not support both types of cuts._ | ||
| ### Pulse | ||
| Send a pulse to an external device, such as a beeper or cash drawer. | ||
| Send a pulse to an external device, such as a beeper or cash drawer. | ||
@@ -558,6 +626,6 @@ let result = encoder | ||
| .encode() | ||
| ## License | ||
| MIT | ||
| MIT |
| { | ||
| "parserOptions": { | ||
| "ecmaVersion": 6 | ||
| }, | ||
| "env": { | ||
| "node": true, | ||
| "es6": true | ||
| }, | ||
| "extends": [ | ||
| "eslint:recommended", | ||
| "google" | ||
| ], | ||
| "rules": { | ||
| "max-len": [ | ||
| 1, | ||
| 120 | ||
| ] | ||
| } | ||
| } |
| !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EscPosEncoder=e()}}(function(){return function(){return function e(t,n,i){function s(r,o){if(!n[r]){if(!t[r]){var h="function"==typeof require&&require;if(!o&&h)return h(r,!0);if(a)return a(r,!0);var c=new Error("Cannot find module '"+r+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[r]={exports:{}};t[r][0].call(l.exports,function(e){return s(t[r][1][e]||e)},l,l.exports,e,t,n,i)}return n[r].exports}for(var a="function"==typeof require&&require,r=0;r<i.length;r++)s(i[r]);return s}}()({1:[function(e,t,n){t.exports=new class{grayscale(e){for(let t=0;t<e.data.length;t+=4){const n=.299*e.data[t]+.587*e.data[t+1]+.114*e.data[t+2];e.data.fill(n,t,t+3)}return e}threshold(e,t){for(let n=0;n<e.data.length;n+=4){const i=.299*e.data[n]+.587*e.data[n+1]+.114*e.data[n+2]<t?0:255;e.data.fill(i,n,n+3)}return e}bayer(e,t){const n=[[15,135,45,165],[195,75,225,105],[60,180,30,150],[240,120,210,90]];for(let i=0;i<e.data.length;i+=4){const s=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2],a=i/4%e.width,r=Math.floor(i/4/e.width),o=Math.floor((s+n[a%4][r%4])/2)<t?0:255;e.data.fill(o,i,i+3)}return e}floydsteinberg(e){const t=e.width,n=new Uint8ClampedArray(e.width*e.height);for(let t=0,i=0;i<e.data.length;t++,i+=4)n[t]=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2];for(let i=0,s=0;s<e.data.length;i++,s+=4){const a=n[i]<129?0:255,r=Math.floor((n[i]-a)/16);e.data.fill(a,s,s+3),n[i+1]+=7*r,n[i+t-1]+=3*r,n[i+t]+=5*r,n[i+t+1]+=1*r}return e}atkinson(e){const t=e.width,n=new Uint8ClampedArray(e.width*e.height);for(let t=0,i=0;i<e.data.length;t++,i+=4)n[t]=.299*e.data[i]+.587*e.data[i+1]+.114*e.data[i+2];for(let i=0,s=0;s<e.data.length;i++,s+=4){const a=n[i]<129?0:255,r=Math.floor((n[i]-a)/8);e.data.fill(a,s,s+3),n[i+1]+=r,n[i+2]+=r,n[i+t-1]+=r,n[i+t]+=r,n[i+t+1]+=r,n[i+2*t]+=r}return e}}},{}],2:[function(e,t,n){t.exports=new class{flatten(e,t){for(let n=0;n<e.data.length;n+=4){const i=e.data[n+3],s=255-i;e.data[n]=(i*e.data[n]+s*t[0])/255,e.data[n+1]=(i*e.data[n+1]+s*t[1])/255,e.data[n+2]=(i*e.data[n+2]+s*t[2])/255,e.data[n+3]=255}return e}}},{}],3:[function(e,t,n){const i=e("./lib/parse-font");n.parseFont=i,n.createCanvas=function(e,t){return Object.assign(document.createElement("canvas"),{width:e,height:t})},n.createImageData=function(e,t,n){switch(arguments.length){case 0:return new ImageData;case 1:return new ImageData(e);case 2:return new ImageData(e,t);default:return new ImageData(e,t,n)}},n.loadImage=function(e,t){return new Promise(function(n,i){const s=Object.assign(document.createElement("img"),t);function a(){s.onload=null,s.onerror=null}s.onload=function(){a(),n(s)},s.onerror=function(){a(),i(new Error('Failed to load the image "'+e+'"'))},s.src=e})}},{"./lib/parse-font":4}],4:[function(e,t,n){"use strict";const i="'([^']+)'|\"([^\"]+)\"|[\\w\\s-]+",s=new RegExp("(bold|bolder|lighter|[1-9]00) +","i"),a=new RegExp("(italic|oblique) +","i"),r=new RegExp("(small-caps) +","i"),o=new RegExp("(ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded) +","i"),h=new RegExp(`([\\d\\.]+)(px|pt|pc|in|cm|mm|%|em|ex|ch|rem|q) *((?:${i})( *, *(?:${i}))*)`),c={};t.exports=(e=>{if(c[e])return c[e];const t=h.exec(e);if(!t)return;const n={weight:"normal",style:"normal",stretch:"normal",variant:"normal",size:parseFloat(t[1]),unit:t[2],family:t[3].replace(/["']/g,"").replace(/ *, */g,",")};let i,l,p,d;const u=e.substring(0,t.index);switch((i=s.exec(u))&&(n.weight=i[1]),(l=a.exec(u))&&(n.style=l[1]),(p=r.exec(u))&&(n.variant=p[1]),(d=o.exec(u))&&(n.stretch=d[1]),n.unit){case"pt":n.size/=.75;break;case"pc":n.size*=16;break;case"in":n.size*=96;break;case"cm":n.size*=96/2.54;break;case"mm":n.size*=96/25.4;break;case"%":break;case"em":case"rem":n.size*=16/.75;break;case"q":n.size*=96/25.4/4}return c[e]=n})},{}],5:[function(e,t,n){const i={cp437:{name:"USA, Standard Europe",languages:["en"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp720:{name:"Arabic",languages:["ar"],offset:128,chars:"éâàçêëèïîّْô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡ًٌٍَُِ≈°∙·√ⁿ²■ "},cp737:{name:"Greek",languages:["el"],offset:128,chars:"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ "},cp775:{name:"Baltic Rim",languages:["et","lt"],offset:128,chars:"ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£Ø×¤ĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’±“¾¶§÷„°∙·¹³²■ "},cp850:{name:"Multilingual",languages:["en"],offset:128,chars:"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´˝˛ˇ˘§÷¸°¨˙űŘř■ "},cp851:{name:"Greek",languages:["el"],offset:128,chars:"ÇüéâäàΆçêëèïîΈÄΉΊ ΌôöΎûùΏÖÜά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ´±υφχ§ψ¸°¨ωϋΰώ■ "},cp852:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´˝˛ˇ˘§÷¸°¨˙űŘř■ "},cp853:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàĉçêëèïîìÄĈÉċĊôöòûùİÖÜĝ£Ĝ×ĵáíóúñÑĞğĤĥ�½Ĵş«»░▒▓│┤ÁÂÀŞ╣║╗╝Żż┐└┴┬├─┼Ŝŝ╚╔╩╦╠═╬¤��ÊËÈıÍÎÏ┘┌█▄�Ì▀ÓßÔÒĠġµĦħÚÛÙŬŭ�´�ℓʼn˘§÷¸°¨˙�³²■ "},cp855:{name:"Cyrillic",languages:["bg"],offset:128,chars:"ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№ыЫзЗшШэЭщЩчЧ§■ "},cp857:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´±�¾¶§÷¸°¨·¹³²■ "},cp858:{name:"Euro",languages:["en"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ "},cp860:{name:"Portuguese",languages:["pt"],offset:128,chars:"ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp861:{name:"Icelandic",languages:["is"],offset:128,chars:"ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp862:{name:"Hebrew",languages:["he"],offset:128,chars:"אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp863:{name:"Canadian French",languages:["fr"],offset:128,chars:"ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp864:{name:"Arabic",languages:["ar"],offset:0,chars:"\0\b\t\n\v\f\r !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�"},cp865:{name:"Nordic",languages:["sv","dk"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp866:{name:"Cyrillic 2",languages:["ru"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ "},cp869:{name:"Greek",languages:["el"],offset:128,chars:"������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄±υφχ§ψ΅°¨ωϋΰώ■ "},cp874:{name:"Thai",languages:["th"],offset:128,chars:"€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"},cp1098:{name:"Farsi",languages:["fa"],offset:128,chars:" ،؛؟ًآﺂاﺎءأﺄؤﺋبﺑﭖﭘتﺗثﺛجﺟﭺﭼ×حﺣخﺧدذرزﮊسﺳشﺷصﺻ«»░▒▓│┤ضﺿﻁﻃ╣║╗╝¤ﻅ┐└┴┬├─┼ﻇع╚╔╩╦╠═╬ ﻊﻋﻌغﻎﻏﻐفﻓ┘┌█▄قﻗ▀ﮎﻛﮒﮔلﻟمﻣنﻧوهﻫﻬﮤﯼﯽﯾـ٠١٢٣٤٥٦٧٨٩■ "},cp1118:{name:"Lithuanian",languages:["lt"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀αβΓπΣσµτΦΘΩδ∞φε⋂≡±≥≤„“÷≈°∙˙√ⁿ²■ "},cp1119:{name:"Lithuanian",languages:["lt"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁё≥≤„“÷≈°∙·√ⁿ²■ "},cp1125:{name:"Ukrainian",languages:["uk"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ "},cp1162:{name:"Thai",languages:["th"],offset:128,chars:"€…‘’“”•–— กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����"},cp2001:{name:"Lithuanian KBL or 771",languages:["lt"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█ĄąČčрстуфхцчшщъыьэюяĘęĖėĮįŠšŲųŪūŽž■ "},cp3001:{name:"Estonian 1 or 1116",languages:["et"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤šŠÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµžŽÚÛÙýݯ´±‗¾¶§÷¸°¨·¹³²■ "},cp3002:{name:"Estonian 2",languages:["et"],offset:128,chars:" ¡¢£¤¥¦§¨©ª«¬®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖרÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ"},cp3011:{name:"Latvian 1",languages:["lv"],offset:128,chars:"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤Ā╢ņ╕╣║╗╝╜╛┐└┴┬├─┼ā╟╚╔╩╦╠═╬╧Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀αßΓπΣσµτΦΘΩδ∞φε∩ĒēĢķĶļĻžŽ∙·√Ņš■ "},cp3012:{name:"Latvian 2 (modified 866)",languages:["lv"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤Ā╢ņ╕╣║╗╝Ō╛┐└┴┬├─┼ā╟╚╔╩╦╠═╬╧Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀рстуфхцчшщъыьэюяĒēĢķĶļĻžŽō·√Ņš■ "},cp3021:{name:"Bulgarian (MIK)",languages:["bg"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3041:{name:"Maltese ISO 646",languages:["mt"],offset:0,chars:"\0\b\t\n\v\f\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZġżħ^_ċabcdefghijklmnopqrstuvwxyzĠŻĦĊ"},cp3840:{name:"Russian (modified 866)",languages:["ru"],offset:128,chars:"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюя≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3841:{name:"Ghost",languages:["ru"],offset:128,chars:"ғәёіїјҝөўүӽӈҹҷє£ҒӘЁІЇЈҜӨЎҮӼӇҸҶЄЪ !\"#$%&'()*+,-./0123456789:;<=>?юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧ∅"},cp3843:{name:"Polish (Mazovia)",languages:["pl"],offset:128,chars:"ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖܢ٥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3844:{name:"Czech (Kamenický)",languages:["cz"],offset:128,chars:"ČüéďäĎŤčěĚĹÍľĺÄÁÉžŽôöÓůÚýÖÜŠĽÝŘťáíóúňŇŮÔšřŕŔ¼§«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3845:{name:"Hungarian (CWI-2)",languages:["hu"],offset:128,chars:"ÇüéâäàåçêëèïîÍÄÁÉæÆőöÓűÚŰÖÜ¢£¥₧ƒáíóúñÑªŐ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3846:{name:"Turkish",languages:["tr"],offset:128,chars:"ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜ¢£¥ŞşáíóúñÑĞğ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "},cp3847:{name:"Brazil ABNT",languages:["pt"],offset:256,chars:""},cp3848:{name:"Brazil ABICOMP",languages:["pt"],offset:160,chars:" ÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖŒÙÚÛÜŸ¨£¦§°¡àáâãäçèéêëìíîïñòóôõöœùúûüÿߪº¿±"},iso88591:{name:"Latin 1",languages:["en"],offset:128,chars:" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},iso88592:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:" Ą˘Ł¤ĽŚ§¨ŠŞŤŹŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"},iso88597:{name:"Greek",languages:["el"],offset:128,chars:" ‘’£€₯¦§¨©ͺ«¬�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"},iso885915:{name:"Latin 9",languages:["fr"],offset:128,chars:" ¡¢£€¥Š§š©ª«¬®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},rk1048:{name:"Kazakh",languages:["kk"],offset:128,chars:"ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"},windows1250:{name:"Latin 2",languages:["hu","pl","cz"],offset:128,chars:"€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"},windows1251:{name:"Cyrillic",languages:["ru"],offset:128,chars:"ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"},windows1252:{name:"Latin",languages:["fr"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"},windows1253:{name:"Greek",languages:["el"],offset:128,chars:"€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�"},windows1254:{name:"Turkish",languages:["tr"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"},windows1255:{name:"Hebrew",languages:["he"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת���"},windows1256:{name:"Arabic",languages:["ar"],offset:128,chars:"€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œں ،¢£¤¥¦§¨©ھ«¬®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûüے"},windows1257:{name:"Baltic Rim",languages:["et","lt"],offset:128,chars:"€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙"},windows1258:{name:"Vietnamese",languages:["vi"],offset:128,chars:"€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"}},s={en:"The quick brown fox jumps over the lazy dog.",jp:"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム",pt:"O próximo vôo à noite sobre o Atlântico, põe freqüentemente o único médico.",fr:"Les naïfs ægithales hâtifs pondant à Noël où il gèle sont sûrs d'être déçus en voyant leurs drôles d'œufs abîmés.",sv:"Flygande bäckasiner söka strax hwila på mjuka tuvor.",dk:"Quizdeltagerne spiste jordbær med fløde",el:"ξεσκεπάζω την ψυχοφθόρα βδελυγμία",tr:"Pijamalı hasta, yağız şoföre çabucak güvendi.",ru:"Съешь же ещё этих мягких французских булок да выпей чаю",hu:"Árvíztűrő tükörfúrógép",pl:"Pchnąć w tę łódź jeża lub ośm skrzyń fig",cz:"Mohu jíst sklo, neublíží mi.",ar:"أنا قادر على أكل الزجاج و هذا لا يؤلمني.",et:"Ma võin klaasi süüa, see ei tee mulle midagi.",lt:"Aš galiu valgyti stiklą ir jis manęs nežeidžia.",bg:"Мога да ям стъкло, то не ми вреди.",is:"Ég get etið gler án þess að meiða mig.",he:"אני יכול לאכול זכוכית וזה לא מזיק לי.",fa:".من می توانم بدونِ احساس درد شيشه بخورم",uk:"Я можу їсти скло, і воно мені не зашкодить.",vi:"Tôi có thể ăn thủy tinh mà không hại gì.",kk:"қазақша",lv:"Es varu ēst stiklu, tas man nekaitē.",mt:"Nista' niekol il-ħġieġ u ma jagħmilli xejn.",th:"ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ"};t.exports=class{static getEncodings(){return Object.keys(i)}static getTestStrings(e){return void 0!==i[e]&&void 0!==i[e].languages?i[e].languages.map(e=>({language:e,string:s[e]})):[]}static supports(e){return void 0!==i[e]&&void 0!==i[e].chars}static encode(e,t){const n=new Uint8Array(t.length);let s="\0".repeat(128),a=128;void 0!==i[e]&&void 0!==i[e].chars&&(s=i[e].chars,a=i[e].offset);for(let e=0;e<t.length;e++){const i=t.codePointAt(e);if(i<128)n[e]=i;else{const r=s.indexOf(t[e]);-1!==r?n[e]=a+r:i<256&&(i<a||i>=a+s.length)?n[e]=i:n[e]=63}}return n}}},{}],6:[function(e,t,n){var i={html:{skipScheme:"html",lineBreakScheme:"html",whitespace:"collapse"}},s=/<\s*br(?:[\s/]*|\s[^>]*)>/gi,a={unix:[/\n/g,"\n"],dos:[/\r\n/g,"\r\n"],mac:[/\r/g,"\r"],html:[s,"<br>"],xhtml:[s,"<br/>"]},r={"ansi-color":/\x1B\[[^m]*m/g,html:/<[^>]*>/g,bbcode:/\[[^]]*\]/g},o={soft:1,hard:1},h={collapse:1,default:1,line:1,all:1},c={all:1,multi:1,none:1},l=/([sm])(\d+)/,p=/[-/\\^$*+?.()|[\]{}]/g;function d(e){return e.replace(p,"\\$&")}var u=t.exports=function(e,t,n){"object"==typeof e&&(e=(n=e).start,t=n.stop),"object"==typeof t&&(n=t,e=e||n.start,t=void 0),t||(t=e,e=0),n||(n={});var s,p,u,g,f,w,m,b,_,y,v,k,x,E,q,L,j,I,A="soft",B="default",R=4,M="all",S="",z="";if(s=n.preset)for(s instanceof Array||(s=[s]),I=0;I<s.length;I++){if(!(L=i[s[I]]))throw new TypeError('preset must be one of "'+Object.keys(i).join('", "')+'"');L.mode&&(A=L.mode),L.whitespace&&(B=L.whitespace),void 0!==L.tabWidth&&(R=L.tabWidth),L.skip&&(p=L.skip),L.skipScheme&&(u=L.skipScheme),L.lineBreak&&(g=L.lineBreak),L.lineBreakScheme&&(f=L.lineBreakScheme),L.respectLineBreaks&&(M=L.respectLineBreaks),void 0!==L.preservedLineIndent&&(m=L.preservedLineIndent),void 0!==L.wrapLineIndent&&(b=L.wrapLineIndent),L.wrapLineIndentBase&&(_=L.wrapLineIndentBase)}if(n.mode){if(!o[n.mode])throw new TypeError('mode must be one of "'+Object.keys(o).join('", "')+'"');A=n.mode}if(n.whitespace){if(!h[n.whitespace])throw new TypeError('whitespace must be one of "'+Object.keys(h).join('", "')+'"');B=n.whitespace}if(void 0!==n.tabWidth){if(!(parseInt(n.tabWidth,10)>=0))throw new TypeError("tabWidth must be a non-negative integer");R=parseInt(n.tabWidth,10)}if(q=new Array(R+1).join(" "),n.respectLineBreaks){if(!c[n.respectLineBreaks]&&!l.test(n.respectLineBreaks))throw new TypeError('respectLineBreaks must be one of "'+Object.keys(c).join('", "')+'", "m<num>", "s<num>"');M=n.respectLineBreaks}if("multi"===M)M="m",w=2;else if(!c[M]){var T=l.exec(M);M=T[1],w=parseInt(T[2],10)}if(void 0!==n.preservedLineIndent){if(!(parseInt(n.preservedLineIndent,10)>=0))throw new TypeError("preservedLineIndent must be a non-negative integer");m=parseInt(n.preservedLineIndent,10)}if(m>0&&(S=new Array(m+1).join(" ")),void 0!==n.wrapLineIndent){if(isNaN(parseInt(n.wrapLineIndent,10)))throw new TypeError("wrapLineIndent must be an integer");b=parseInt(n.wrapLineIndent,10)}if(n.wrapLineIndentBase&&(_=n.wrapLineIndentBase),_){if(void 0===b)throw new TypeError("wrapLineIndent must be specified when wrapLineIndentBase is specified");if(_ instanceof RegExp)E=_;else{if("string"!=typeof _)throw new TypeError("wrapLineIndentBase must be either a RegExp object or a string");E=new RegExp(d(_))}}else if(b>0)z=new Array(b+1).join(" ");else if(b<0)throw new TypeError("wrapLineIndent must be non-negative when a base is not specified");if(n.skipScheme){if(!r[n.skipScheme])throw new TypeError('skipScheme must be one of "'+Object.keys(r).join('", "')+'"');u=n.skipScheme}if(n.skip&&(p=n.skip),p)if(p instanceof RegExp)(y=p).global||(j="g",y.ignoreCase&&(j+="i"),y.multiline&&(j+="m"),y=new RegExp(y.source,j));else{if("string"!=typeof p)throw new TypeError("skip must be either a RegExp object or a string");y=new RegExp(d(p),"g")}if(!y&&u&&(y=r[u]),n.lineBreakScheme){if(!a[n.lineBreakScheme])throw new TypeError('lineBreakScheme must be one of "'+Object.keys(a).join('", "')+'"');f=n.lineBreakScheme}if(n.lineBreak&&(g=n.lineBreak),f&&(L=a[f])&&(v=L[0],k=L[1]),g)if(g instanceof Array&&(1===g.length?g=g[0]:g.length>=2&&(g[0]instanceof RegExp?(v=g[0],"string"==typeof g[1]&&(k=g[1])):g[1]instanceof RegExp?(v=g[1],"string"==typeof g[0]&&(k=g[0])):"string"==typeof g[0]&&"string"==typeof g[1]?(v=new RegExp(d(g[0]),"g"),k=g[1]):g=g[0])),"string"==typeof g)k=g,v||(v=new RegExp(d(g),"g"));else if(g instanceof RegExp)v=g;else if(!(g instanceof Array))throw new TypeError("lineBreak must be a RegExp object, a string, or an array consisted of a RegExp object and a string");v||(v=/\n/g,k="\n"),j="g",v.ignoreCase&&(j+="i"),v.multiline&&(j+="m"),x=new RegExp("\\s*(?:"+v.source+")(?:"+v.source+"|\\s)*",j),v.global||(v=new RegExp(v.source,j));var C="hard"===A?/\b/:/(\S+\s+)/,O=new Array(e+1).join(" "),U="default"===B||"collapse"===B,N="collapse"===B,W="line"===B,P="all"===B,D=/\t/g,F=/ +/g,G=/^\s+/,H=/\s+$/,$=/\S/,K=/\s/,Q=t-e;return function(n){var i;if(n=n.toString().replace(D,q),!k){if(v.lastIndex=0,!(i=v.exec(n)))throw new TypeError("Line break string for the output not specified");k=i[0]}var s,a,r,o,h,c,l,p,d,u=0;for(s=[],x.lastIndex=0,i=x.exec(n);i;){if(s.push(n.substring(u,i.index)),"none"!==M){for(r=[],o=0,v.lastIndex=0,a=v.exec(i[0]);a;)r.push(i[0].substring(o,a.index)),o=a.index+a[0].length,a=v.exec(i[0]);r.push(i[0].substring(o)),s.push({type:"break",breaks:r})}else h=N?" ":i[0].replace(v,""),s.push({type:"break",remaining:h});u=i.index+i[0].length,i=x.exec(n)}if(s.push(n.substring(u)),y)for(d=[],c=0;c<s.length;c++){var g=s[c];if("string"!=typeof g)d.push(g);else{for(u=0,y.lastIndex=0,i=y.exec(g);i;)d.push(g.substring(u,i.index)),d.push({type:"skip",value:i[0]}),u=i.index+i[0].length,i=y.exec(g);d.push(g.substring(u))}}else d=s;var f=[];for(c=0;c<d.length;c++){var m=d[c];if("string"!=typeof m)f.push(m);else{N&&(m=m.replace(F," "));var _=m.split(C),L=[];for(l=0;l<_.length;l++){var j=_[l];if("hard"===A)for(p=0;p<j.length;p+=Q)L.push(j.slice(p,p+Q));else L.push(j)}f=f.concat(L)}}var I,B=0,R=e+S.length,T=[O+S],V=0,J=!0,X=!0,Y=z;function Z(n){var i,s,a,r=T[B];if(P)R>t&&(V=V||t,a=r.length-(R-V),T[B]=r.substring(0,a)),V=0;else{for(i=r.length-1;i>=e&&" "===r[i];)i--;for(;i>=e&&K.test(r[i]);)i--;++i!==r.length&&(T[B]=r.substring(0,i)),X&&J&&W&&R>t&&(a=r.length-(R-t))<i&&(a=i)}if(X&&(X=!1,E&&(i=T[B].substring(e).search(E),Y=i>=0&&i+b>0?new Array(i+b+1).join(" "):"")),a){for(;a+Q<r.length;)P?(s=r.substring(a,a+Q),T.push(O+Y+s)):T.push(O+Y),a+=Q,B++;if(!n)return s=r.substring(a),Y+s;P?(s=r.substring(a),T.push(O+Y+s)):T.push(O+Y),B++}return""}for(c=0;c<f.length;c++){var ee=f[c];if(""!==ee)if("string"==typeof ee){for(var te;;){if(te=void 0,R+ee.length>t&&R+(te=ee.replace(H,"")).length>t&&""!==te&&R>e){if(I=Z(!1),T.push(O+Y),B++,R=e+Y.length,I){T[B]+=I,R+=I.length,J=!0;continue}!U&&(!W||X&&J)||(ee=ee.replace(G,"")),J=!1}else J&&(U||W&&(!X||!J)?""!==(ee=ee.replace(G,""))&&(J=!1):$.test(ee)&&(J=!1));break}P&&te&&R+te.length>t&&(V=R+te.length),T[B]+=ee,R+=ee.length}else if("break"===ee.type)if("none"!==M){var ne=ee.breaks,ie=ne.length-1;if("s"===M){for(l=0;l<ie;l++)ne[l+1].length<w?ne[l+1]=N?" ":ne[l]+ne[l+1]:(P&&(T[B]+=ne[l],R+=ne[l].length),Z(!0),T.push(O+S),B++,R=e+S.length,X=J=!0);(!J||P||W&&X)&&((N||!J&&""===ne[ie])&&(ne[ie]=" "),T[B]+=ne[ie],R+=ne[ie].length)}else if("m"===M&&ie<w)(!J||P||W&&X)&&(N?ee=" ":(ee=ne.join(""),J||""!==ee||(ee=" ")),T[B]+=ee,R+=ee.length);else if(U){for(Z(!0),l=0;l<ie;l++)T.push(O+S),B++;R=e+S.length,X=J=!0}else for((P||X&&J)&&(T[B]+=ne[0],R+=ne[0].length),l=0;l<ie;l++)Z(!0),T.push(O+S+ne[l+1]),B++,R=e+S.length+ne[l+1].length,X=J=!0}else(!J||P||W&&X)&&(ee=ee.remaining,(N||!J&&""===ee)&&(ee=" "),T[B]+=ee,R+=ee.length);else"skip"===ee.type&&(R>t&&(I=Z(!1),T.push(O+Y),B++,R=e+Y.length,I&&(T[B]+=I,R+=I.length),J=!0),T[B]+=ee.value)}return Z(!0),T.join(k)}};u.soft=u,u.hard=function(){var e=[].slice.call(arguments),t=e.length-1;return"object"==typeof e[t]?e[t].mode="hard":e.push({mode:"hard"}),u.apply(null,e)},u.wrap=function(e){var t=[].slice.call(arguments);return t.shift(),u.apply(null,t)(e)}},{}],7:[function(e,t,n){const i=e("linewrap"),{createCanvas:s}=e("canvas"),a=e("canvas-dither"),r=e("canvas-flatten"),o=e("codepage-encoder"),h={epson:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp851:11,cp853:12,cp857:13,cp737:14,iso88597:15,windows1252:16,cp866:17,cp852:18,cp858:19,cp720:32,cp775:33,cp855:34,cp861:35,cp862:36,cp864:37,cp869:38,iso88592:39,iso885915:40,cp1098:41,cp1118:42,cp1119:43,cp1125:44,windows1250:45,windows1251:46,windows1253:47,windows1254:48,windows1255:49,windows1256:50,windows1257:51,windows1258:52,rk1048:53},zjiang:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,windows1252:16,cp866:17,cp852:18,cp858:19,windows1255:32,cp861:56,cp855:60,cp857:61,cp862:62,cp864:63,cp737:64,cp851:65,cp869:66,cp1119:68,cp1118:69,windows1250:72,windows1251:73,cp3840:74,cp3843:76,cp3844:77,cp3845:78,cp3846:79,cp3847:80,cp3848:81,cp2001:83,cp3001:84,cp3002:85,cp3011:86,cp3012:87,cp3021:88,cp3041:89,windows1253:90,windows1254:91,windows1256:92,cp720:93,windows1258:94,cp775:95},bixolon:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,cp851:11,cp858:19},star:{cp437:0,shiftjis:1,cp850:2,cp860:3,cp863:4,cp865:5,windows1252:16,cp866:17,cp852:18,cp858:19},legacy:{cp437:0,cp737:64,cp850:2,cp775:95,cp852:18,cp855:60,cp857:61,cp858:19,cp860:3,cp861:56,cp862:62,cp863:4,cp864:28,cp865:5,cp866:17,cp869:66,cp936:255,cp949:253,cp950:254,cp1252:16,iso88596:22,shiftjis:252,windows874:30,windows1250:72,windows1251:73,windows1252:71,windows1253:90,windows1254:91,windows1255:32,windows1256:92,windows1257:25,windows1258:94}};class c{constructor(e){this._reset(e)}_reset(e){this._options=Object.assign({width:null,embedded:!1,wordWrap:!0,imageMode:"column",codepageMapping:"epson",codepageCandidates:["cp437","cp858","cp860","cp861","cp863","cp865","cp852","cp857","cp855","cp866","cp869"]},e),this._embedded=this._options.width&&this._options.embedded,this._buffer=[],this._queued=[],this._cursor=0,this._codepage="ascii",this._state={codepage:0,align:"left",bold:!1,italic:!1,underline:!1,invert:!1,width:1,height:1}}_encode(e){if("auto"!=this._codepage)return o.encode(this._codepage,e);let t;t="string"==typeof this._options.codepageMapping?h[this._options.codepageMapping]:this._options.codepageMapping;const n=o.autoEncode(e,this._options.codepageCandidates);let i=0;for(let e=0;e<n.length;e++)i+=3+n[e].bytes.byteLength;const s=new Uint8Array(i);let a=0;for(let e=0;e<n.length;e++)s.set([27,116,t[n[e].codepage]],a),s.set(n[e].bytes,a+3),a+=3+n[e].bytes.byteLength,this._state.codepage=t[n[e].codepage];return s}_queue(e){e.forEach(e=>this._queued.push(e))}_flush(){if(this._embedded){let e=this._options.width-this._cursor;if("left"==this._state.align&&this._queued.push(new Array(e).fill(32)),"center"==this._state.align){const t=e%2;(e>>=1)>0&&this._queued.push(new Array(e).fill(32)),e+t>0&&this._queued.unshift(new Array(e+t).fill(32))}"right"==this._state.align&&this._queued.unshift(new Array(e).fill(32))}this._buffer=this._buffer.concat(this._queued),this._queued=[],this._cursor=0}_wrap(e,t){if(t||this._options.wordWrap&&this._options.width){const n="-".repeat(this._cursor);return i(t||this._options.width,{lineBreak:"\n",whitespace:"all"})(n+e).substring(this._cursor).split("\n")}return[e]}_restoreState(){this.bold(this._state.bold),this.italic(this._state.italic),this.underline(this._state.underline),this.invert(this._state.invert),this._queue([27,116,this._state.codepage])}_getCodepageIdentifier(e){let t;return(t="string"==typeof this._options.codepageMapping?h[this._options.codepageMapping]:this._options.codepageMapping)[e]}initialize(){return this._queue([27,64]),this._flush(),this}codepage(e){if("auto"===e)return this._codepage=e,this;if(!o.supports(e))throw new Error("Unknown codepage");let t;if(void 0===(t="string"==typeof this._options.codepageMapping?h[this._options.codepageMapping]:this._options.codepageMapping)[e])throw new Error("Codepage not supported by printer");return this._codepage=e,this._state.codepage=t[e],this._queue([27,116,t[e]]),this}text(e,t){const n=this._wrap(e,t);for(let e=0;e<n.length;e++){const t=this._encode(n[e]);this._queue([t]),this._cursor+=n[e].length*this._state.width,this._options.width&&!this._embedded&&(this._cursor=this._cursor%this._options.width),e<n.length-1&&this.newline()}return this}newline(){return this._flush(),this._queue([10,13]),this._embedded&&this._restoreState(),this}line(e,t){return this.text(e,t),this.newline(),this}underline(e){return void 0===e&&(e=!this._state.underline),this._state.underline=e,this._queue([27,45,Number(e)]),this}italic(e){return void 0===e&&(e=!this._state.italic),this._state.italic=e,this._queue([27,52,Number(e)]),this}bold(e){return void 0===e&&(e=!this._state.bold),this._state.bold=e,this._queue([27,69,Number(e)]),this}width(e){if(void 0===e&&(e=1),"number"!=typeof e)throw new Error("Width must be a number");if(e<1||e>8)throw new Error("Width must be between 1 and 8");return this._state.width=e,this._queue([29,33,this._state.height-1|this._state.width-1<<4]),this}height(e){if(void 0===e&&(e=1),"number"!=typeof e)throw new Error("Height must be a number");if(e<1||e>8)throw new Error("Height must be between 1 and 8");return this._state.height=e,this._queue([29,33,this._state.height-1|this._state.width-1<<4]),this}invert(e){return void 0===e&&(e=!this._state.invert),this._state.invert=e,this._queue([29,66,Number(e)]),this}size(e){return e="small"===e?1:0,this._queue([27,77,e]),this}align(e){const t={left:0,center:1,right:2};if(!(e in t))throw new Error("Unknown alignment");return this._state.align=e,this._embedded||this._queue([27,97,t[e]]),this}table(e,t){0!=this._cursor&&this.newline();for(let n=0;n<t.length;n++){const s=[];let a=0;for(let r=0;r<e.length;r++){const o=[];if("string"==typeof t[n][r]){const s=i(e[r].width,{lineBreak:"\n"})(t[n][r]).split("\n");for(let t=0;t<s.length;t++)"right"==e[r].align?o[t]=this._encode(s[t].padStart(e[r].width)):o[t]=this._encode(s[t].padEnd(e[r].width))}if("function"==typeof t[n][r]){const i=new c(Object.assign({},this._options,{width:e[r].width,embedded:!0}));i._codepage=this._codepage,i.align(e[r].align),t[n][r](i);const s=i.encode();let a=[];for(let e=0;e<s.byteLength;e++)e<s.byteLength-1&&10===s[e]&&13===s[e+1]?(o.push(a),a=[],e++):a.push(s[e]);a.length&&o.push(a)}a=Math.max(a,o.length),s[r]=o}for(let t=0;t<e.length;t++)if(s[t].length<a)for(let n=s[t].length;n<a;n++){let n="top";void 0!==e[t].verticalAlign&&(n=e[t].verticalAlign),"bottom"==n?s[t].unshift(new Array(e[t].width).fill(32)):s[t].push(new Array(e[t].width).fill(32))}for(let t=0;t<a;t++){for(let n=0;n<e.length;n++)void 0!==e[n].marginLeft&&this.raw(new Array(e[n].marginLeft).fill(32)),this.raw(s[n][t]),void 0!==e[n].marginRight&&this.raw(new Array(e[n].marginRight).fill(32));this.newline()}}return this}rule(e){return e=Object.assign({style:"single",width:this._options.width||10},e||{}),this._queue([27,116,this._getCodepageIdentifier("cp437"),new Array(e.width).fill("double"===e.style?205:196)]),this._queue([27,116,this._state.codepage]),this.newline(),this}box(e,t){let n;n="double"==(e=Object.assign({style:"single",width:this._options.width||30,marginLeft:0,marginRight:0,paddingLeft:0,paddingRight:0},e||{})).style?[201,187,200,188,205,186]:[218,191,192,217,196,179],0!=this._cursor&&this.newline(),this._restoreState(),this._queue([27,116,this._getCodepageIdentifier("cp437")]),this._queue([new Array(e.marginLeft).fill(32),n[0],new Array(e.width-2).fill(n[4]),n[1],new Array(e.marginRight).fill(32)]),this.newline();const s=[];if("string"==typeof t){const n=i(e.width-2-e.paddingLeft-e.paddingRight,{lineBreak:"\n"})(t).split("\n");for(let t=0;t<n.length;t++)"right"==e.align?s[t]=this._encode(n[t].padStart(e.width-2-e.paddingLeft-e.paddingRight)):s[t]=this._encode(n[t].padEnd(e.width-2-e.paddingLeft-e.paddingRight))}if("function"==typeof t){const n=new c(Object.assign({},this._options,{width:e.width-2-e.paddingLeft-e.paddingRight,embedded:!0}));n._codepage=this._codepage,n.align(e.align),t(n);const i=n.encode();let a=[];for(let e=0;e<i.byteLength;e++)e<i.byteLength-1&&10===i[e]&&13===i[e+1]?(s.push(a),a=[],e++):a.push(i[e]);a.length&&s.push(a)}for(let t=0;t<s.length;t++)this._queue([new Array(e.marginLeft).fill(32),n[5],new Array(e.paddingLeft).fill(32)]),this._queue([s[t]]),this._restoreState(),this._queue([27,116,this._getCodepageIdentifier("cp437")]),this._queue([new Array(e.paddingRight).fill(32),n[5],new Array(e.marginRight).fill(32)]),this.newline();return this._queue([new Array(e.marginLeft).fill(32),n[2],new Array(e.width-2).fill(n[4]),n[3],new Array(e.marginRight).fill(32)]),this._restoreState(),this.newline(),this}barcode(e,t,n){if(this._embedded)throw new Error("Barcodes are not supported in table cells or boxes");const i={upca:0,upce:1,ean13:2,ean8:3,code39:4,coda39:4,itf:5,codabar:6,code93:72,code128:73,"gs1-128":80,"gs1-databar-omni":81,"gs1-databar-truncated":82,"gs1-databar-limited":83,"gs1-databar-expanded":84,"code128-auto":85};if(!(t in i))throw new Error("Symbology not supported by printer");{const s=o.encode("ascii",e);0!=this._cursor&&this.newline(),this._queue([29,104,n,29,119,"code39"===t?2:3]),"code128"==t&&123!==s[0]?this._queue([29,107,i[t],s.length+2,123,66,s]):i[t]>64?this._queue([29,107,i[t],s.length,s]):this._queue([29,107,i[t],s,0])}return this._flush(),this}qrcode(e,t,n,i){if(this._embedded)throw new Error("QR codes are not supported in table cells or boxes");this._queue([10]);const s={1:49,2:50};if(void 0===t&&(t=2),!(t in s))throw new Error("Model must be 1 or 2");if(this._queue([29,40,107,4,0,49,65,s[t],0]),void 0===n&&(n=6),"number"!=typeof n)throw new Error("Size must be a number");if(n<1||n>8)throw new Error("Size must be between 1 and 8");this._queue([29,40,107,3,0,49,67,n]);const a={l:48,m:49,q:50,h:51};if(void 0===i&&(i="m"),!(i in a))throw new Error("Error level must be l, m, q or h");this._queue([29,40,107,3,0,49,69,a[i]]);const r=o.encode("iso88591",e),h=r.length+3;return this._queue([29,40,107,h%255,h/255,49,80,48,r]),this._queue([29,40,107,3,0,49,81,48]),this._flush(),this}image(e,t,n,i,o){if(this._embedded)throw new Error("Images are not supported in table cells or boxes");if(t%8!=0)throw new Error("Width must be a multiple of 8");if(n%8!=0)throw new Error("Height must be a multiple of 8");void 0===i&&(i="threshold"),void 0===o&&(o=128);const h=s(t,n).getContext("2d");h.drawImage(e,0,0,t,n);let c=h.getImageData(0,0,t,n);switch(c=r.flatten(c,[255,255,255]),i){case"threshold":c=a.threshold(c,o);break;case"bayer":c=a.bayer(c,o);break;case"floydsteinberg":c=a.floydsteinberg(c);break;case"atkinson":c=a.atkinson(c)}const l=(e,i)=>e<t&&i<n?c.data[4*(t*i+e)]>0?0:1:0;return 0!=this._cursor&&this.newline(),"column"==this._options.imageMode&&(this._queue([27,51,36]),((e,t)=>{const n=[];for(let i=0;i<Math.ceil(t/24);i++){const t=new Uint8Array(3*e);for(let n=0;n<e;n++)for(let e=0;e<3;e++)for(let s=0;s<8;s++)t[3*n+e]|=l(n,24*i+s+8*e)<<7-s;n.push(t)}return n})(t,n).forEach(e=>{this._queue([27,42,33,255&t,t>>8&255,e,10])}),this._queue([27,50])),"raster"==this._options.imageMode&&this._queue([29,118,48,0,t>>3&255,t>>3>>8&255,255&n,n>>8&255,((e,t)=>{const n=new Uint8Array(e*t>>3);for(let i=0;i<t;i++)for(let t=0;t<e;t+=8)for(let s=0;s<8;s++)n[i*(e>>3)+(t>>3)]|=l(t+s,i)<<7-s;return n})(t,n)]),this._flush(),this}cut(e){if(this._embedded)throw new Error("Cut is not supported in table cells or boxes");let t=0;return"partial"==e&&(t=1),this._queue([29,86,t]),this}pulse(e,t,n){if(this._embedded)throw new Error("Pulse is not supported in table cells or boxes");return void 0===e&&(e=0),void 0===t&&(t=100),void 0===n&&(n=500),t=Math.min(500,Math.round(t/2)),n=Math.min(500,Math.round(n/2)),this._queue([27,112,e?1:0,255&t,255&n]),this}raw(e){return this._queue(e),this}encode(){this._flush();let e=0;this._buffer.forEach(t=>{"number"==typeof t?e++:e+=t.length});const t=new Uint8Array(e);let n=0;return this._buffer.forEach(e=>{"number"==typeof e?(t[n]=e,n++):(t.set(e,n),n+=e.length)}),this._reset(),t}}t.exports=c},{canvas:3,"canvas-dither":1,"canvas-flatten":2,"codepage-encoder":5,linewrap:6}]},{},[7])(7)}); |
-239
| export default class EscPosEncoder { | ||
| /** | ||
| * Initialize the printer | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| initialize(): EscPosEncoder; | ||
| /** | ||
| * Change the code page | ||
| * | ||
| * @param {string} codepage The codepage that we set the printer to | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| codepage(codepage: string): EscPosEncoder; | ||
| /** | ||
| * Print text | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| text(value: string, wrap?: number): EscPosEncoder; | ||
| /** | ||
| * Print a newline | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| newline(): EscPosEncoder; | ||
| /** | ||
| * Print text, followed by a newline | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| line(value: string, wrap?: number): EscPosEncoder; | ||
| /** | ||
| * Underline text | ||
| * | ||
| * @param {boolean|number} value true to turn on underline, false to turn off, or 2 for double underline | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| underline(value?: boolean | number): EscPosEncoder; | ||
| /** | ||
| * Italic text | ||
| * | ||
| * @param {boolean} value true to turn on italic, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| italic(value?: boolean): EscPosEncoder; | ||
| /** | ||
| * Bold text | ||
| * | ||
| * @param {boolean} value true to turn on bold, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| bold(value?: boolean): EscPosEncoder; | ||
| /** | ||
| * Change width of text | ||
| * | ||
| * @param {number} width The width of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| width(width: number): EscPosEncoder; | ||
| /** | ||
| * Change height of text | ||
| * | ||
| * @param {number} height The height of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| height(height: number): EscPosEncoder; | ||
| /** | ||
| * Invert text | ||
| * | ||
| * @param {boolean} value true to turn on white text on black, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| invert(value: boolean): EscPosEncoder; | ||
| /** | ||
| * Change text size | ||
| * | ||
| * @param {string} value small or normal | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| size(value: string): EscPosEncoder; | ||
| /** | ||
| * Change text alignment | ||
| * | ||
| * @param {string} value left, center or right | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| align(value: string): EscPosEncoder; | ||
| /** | ||
| * Insert a table | ||
| * | ||
| * @param {array} columns The column definitions | ||
| * @param {array} data Array containing rows. Each row is an array containing cells. | ||
| * Each cell can be a string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| table(columns: any[], data: any[]): EscPosEncoder; | ||
| /** | ||
| * Insert a horizontal rule | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the line, either single or double | ||
| * - width: The width of the line, by default the width of the paper | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| rule(options: Object): EscPosEncoder; | ||
| /** | ||
| * Insert a horizontal rule | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the border, either single or double | ||
| * - width: The width of the box, by default the width of the paper, if specified | ||
| * - marginLeft: Space between the left border and the left side of the paper | ||
| * - marginRight: Space between the right border and the right side of the paper | ||
| * - paddingLeft: Space between the contents and the left border of the box | ||
| * - paddingRight: Space between the contents and the right border of the box | ||
| * @param {string|function} contents A string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| box(options: Object, contents: string | Function): EscPosEncoder; | ||
| /** | ||
| * Barcode | ||
| * | ||
| * @param {string} value the value of the barcode | ||
| * @param {string} symbology the type of the barcode | ||
| * @param {number} height height of the barcode | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| barcode(value: string, symbology: string, height: number): EscPosEncoder; | ||
| /** | ||
| * QR code | ||
| * | ||
| * @param {string} value the value of the qr code | ||
| * @param {number} model model of the qrcode, either 1 or 2 | ||
| * @param {number} size size of the qrcode, a value between 1 and 8 | ||
| * @param {string} errorlevel the amount of error correction used, either 'l', 'm', 'q', 'h' | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| qrcode(value: string, model?: number, size?: number, errorlevel?: string): EscPosEncoder; | ||
| /** | ||
| * Image | ||
| * | ||
| * @param {object} element an element, like a canvas or image that needs to be printed | ||
| * @param {number} width width of the image on the printer | ||
| * @param {number} height height of the image on the printer | ||
| * @param {string} algorithm the dithering algorithm for making the image black and white | ||
| * @param {number} threshold threshold for the dithering algorithm | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| image( | ||
| element: Object, | ||
| width: number, | ||
| height: number, | ||
| algorithm: string, | ||
| threshold: number | ||
| ): EscPosEncoder; | ||
| /** | ||
| * Cut paper | ||
| * | ||
| * @param {string} value full or partial. When not specified a full cut will be assumed | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| cut(value?: string): EscPosEncoder; | ||
| /** | ||
| * Pulse | ||
| * | ||
| * @param {number} device 0 or 1 for on which pin the device is connected, default of 0 | ||
| * @param {number} on Time the pulse is on in milliseconds, default of 100 | ||
| * @param {number} off Time the pulse is off in milliseconds, default of 500 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| pulse(device?: number, on?: number, off?: number): EscPosEncoder; | ||
| /** | ||
| * Add raw printer commands | ||
| * | ||
| * @param {array} data raw bytes to be included | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| raw(data: any[]): EscPosEncoder; | ||
| /** | ||
| * Encode all previous commands | ||
| * | ||
| * @return {Uint8Array} Return the encoded bytes | ||
| * | ||
| */ | ||
| encode(): Uint8Array; | ||
| } |
| const linewrap = require('linewrap'); | ||
| const {createCanvas} = require('canvas'); | ||
| const Dither = require('canvas-dither'); | ||
| const Flatten = require('canvas-flatten'); | ||
| const CodepageEncoder = require('codepage-encoder'); | ||
| const codepageMappings = { | ||
| epson: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp851': 0x0b, | ||
| 'cp853': 0x0c, | ||
| 'cp857': 0x0d, | ||
| 'cp737': 0x0e, | ||
| 'iso88597': 0x0f, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| 'cp720': 0x20, | ||
| 'cp775': 0x21, | ||
| 'cp855': 0x22, | ||
| 'cp861': 0x23, | ||
| 'cp862': 0x24, | ||
| 'cp864': 0x25, | ||
| 'cp869': 0x26, | ||
| 'iso88592': 0x27, | ||
| 'iso885915': 0x28, | ||
| 'cp1098': 0x29, | ||
| 'cp1118': 0x2a, | ||
| 'cp1119': 0x2b, | ||
| 'cp1125': 0x2c, | ||
| 'windows1250': 0x2d, | ||
| 'windows1251': 0x2e, | ||
| 'windows1253': 0x2f, | ||
| 'windows1254': 0x30, | ||
| 'windows1255': 0x31, | ||
| 'windows1256': 0x32, | ||
| 'windows1257': 0x33, | ||
| 'windows1258': 0x34, | ||
| 'rk1048': 0x35, | ||
| }, | ||
| zjiang: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| 'windows1255': 0x20, | ||
| 'cp861': 0x38, | ||
| 'cp855': 0x3c, | ||
| 'cp857': 0x3d, | ||
| 'cp862': 0x3e, | ||
| 'cp864': 0x3f, | ||
| 'cp737': 0x40, | ||
| 'cp851': 0x41, | ||
| 'cp869': 0x42, | ||
| 'cp1119': 0x44, | ||
| 'cp1118': 0x45, | ||
| 'windows1250': 0x48, | ||
| 'windows1251': 0x49, | ||
| 'cp3840': 0x4a, | ||
| 'cp3843': 0x4c, | ||
| 'cp3844': 0x4d, | ||
| 'cp3845': 0x4e, | ||
| 'cp3846': 0x4f, | ||
| 'cp3847': 0x50, | ||
| 'cp3848': 0x51, | ||
| 'cp2001': 0x53, | ||
| 'cp3001': 0x54, | ||
| 'cp3002': 0x55, | ||
| 'cp3011': 0x56, | ||
| 'cp3012': 0x57, | ||
| 'cp3021': 0x58, | ||
| 'cp3041': 0x59, | ||
| 'windows1253': 0x5a, | ||
| 'windows1254': 0x5b, | ||
| 'windows1256': 0x5c, | ||
| 'cp720': 0x5d, | ||
| 'windows1258': 0x5e, | ||
| 'cp775': 0x5f, | ||
| }, | ||
| bixolon: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'cp851': 0x0b, | ||
| 'cp858': 0x13, | ||
| }, | ||
| star: { | ||
| 'cp437': 0x00, | ||
| 'shiftjis': 0x01, | ||
| 'cp850': 0x02, | ||
| 'cp860': 0x03, | ||
| 'cp863': 0x04, | ||
| 'cp865': 0x05, | ||
| 'windows1252': 0x10, | ||
| 'cp866': 0x11, | ||
| 'cp852': 0x12, | ||
| 'cp858': 0x13, | ||
| }, | ||
| legacy: { | ||
| 'cp437': 0x00, | ||
| 'cp737': 0x40, | ||
| 'cp850': 0x02, | ||
| 'cp775': 0x5f, | ||
| 'cp852': 0x12, | ||
| 'cp855': 0x3c, | ||
| 'cp857': 0x3d, | ||
| 'cp858': 0x13, | ||
| 'cp860': 0x03, | ||
| 'cp861': 0x38, | ||
| 'cp862': 0x3e, | ||
| 'cp863': 0x04, | ||
| 'cp864': 0x1c, | ||
| 'cp865': 0x05, | ||
| 'cp866': 0x11, | ||
| 'cp869': 0x42, | ||
| 'cp936': 0xff, | ||
| 'cp949': 0xfd, | ||
| 'cp950': 0xfe, | ||
| 'cp1252': 0x10, | ||
| 'iso88596': 0x16, | ||
| 'shiftjis': 0xfc, | ||
| 'windows874': 0x1e, | ||
| 'windows1250': 0x48, | ||
| 'windows1251': 0x49, | ||
| 'windows1252': 0x47, | ||
| 'windows1253': 0x5a, | ||
| 'windows1254': 0x5b, | ||
| 'windows1255': 0x20, | ||
| 'windows1256': 0x5c, | ||
| 'windows1257': 0x19, | ||
| 'windows1258': 0x5e, | ||
| }, | ||
| }; | ||
| /** | ||
| * Create a byte stream based on commands for ESC/POS printers | ||
| */ | ||
| class EscPosEncoder { | ||
| /** | ||
| * Create a new object | ||
| * | ||
| * @param {object} options Object containing configuration options | ||
| */ | ||
| constructor(options) { | ||
| this._reset(options); | ||
| } | ||
| /** | ||
| * Reset the state of the object | ||
| * | ||
| * @param {object} options Object containing configuration options | ||
| */ | ||
| _reset(options) { | ||
| this._options = Object.assign({ | ||
| width: null, | ||
| embedded: false, | ||
| wordWrap: true, | ||
| imageMode: 'column', | ||
| codepageMapping: 'epson', | ||
| codepageCandidates: [ | ||
| 'cp437', 'cp858', 'cp860', 'cp861', 'cp863', 'cp865', | ||
| 'cp852', 'cp857', 'cp855', 'cp866', 'cp869', | ||
| ], | ||
| }, options); | ||
| this._embedded = this._options.width && this._options.embedded; | ||
| this._buffer = []; | ||
| this._queued = []; | ||
| this._cursor = 0; | ||
| this._codepage = 'ascii'; | ||
| this._state = { | ||
| 'codepage': 0, | ||
| 'align': 'left', | ||
| 'bold': false, | ||
| 'italic': false, | ||
| 'underline': false, | ||
| 'invert': false, | ||
| 'width': 1, | ||
| 'height': 1, | ||
| }; | ||
| } | ||
| /** | ||
| * Encode a string with the current code page | ||
| * | ||
| * @param {string} value String to encode | ||
| * @return {object} Encoded string as a ArrayBuffer | ||
| * | ||
| */ | ||
| _encode(value) { | ||
| if (this._codepage != 'auto') { | ||
| return CodepageEncoder.encode(this._codepage, value); | ||
| } | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| const fragments = CodepageEncoder.autoEncode(value, this._options.codepageCandidates); | ||
| let length = 0; | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| length += 3 + fragments[f].bytes.byteLength; | ||
| } | ||
| const buffer = new Uint8Array(length); | ||
| let i = 0; | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| buffer.set([0x1b, 0x74, codepages[fragments[f].codepage]], i); | ||
| buffer.set(fragments[f].bytes, i + 3); | ||
| i += 3 + fragments[f].bytes.byteLength; | ||
| this._state.codepage = codepages[fragments[f].codepage]; | ||
| } | ||
| return buffer; | ||
| } | ||
| /** | ||
| * Add commands to the queue | ||
| * | ||
| * @param {array} value Add array of numbers, arrays, buffers or Uint8Arrays to add to the buffer | ||
| * | ||
| */ | ||
| _queue(value) { | ||
| value.forEach((item) => this._queued.push(item)); | ||
| } | ||
| /** | ||
| * Flush current queue to the buffer | ||
| * | ||
| */ | ||
| _flush() { | ||
| if (this._embedded) { | ||
| let indent = this._options.width - this._cursor; | ||
| if (this._state.align == 'left') { | ||
| this._queued.push((new Array(indent)).fill(0x20)); | ||
| } | ||
| if (this._state.align == 'center') { | ||
| const remainder = indent % 2; | ||
| indent = indent >> 1; | ||
| if (indent > 0) { | ||
| this._queued.push((new Array(indent)).fill(0x20)); | ||
| } | ||
| if (indent + remainder > 0) { | ||
| this._queued.unshift((new Array(indent + remainder)).fill(0x20)); | ||
| } | ||
| } | ||
| if (this._state.align == 'right') { | ||
| this._queued.unshift((new Array(indent)).fill(0x20)); | ||
| } | ||
| } | ||
| this._buffer = this._buffer.concat(this._queued); | ||
| this._queued = []; | ||
| this._cursor = 0; | ||
| } | ||
| /** | ||
| * Wrap the text while respecting the position of the cursor | ||
| * | ||
| * @param {string} value String to wrap after the width of the paper has been reached | ||
| * @param {number} position Position on which to force a wrap | ||
| * @return {array} Array with each line | ||
| */ | ||
| _wrap(value, position) { | ||
| if (position || (this._options.wordWrap && this._options.width)) { | ||
| const indent = '-'.repeat(this._cursor); | ||
| const w = linewrap(position || this._options.width, {lineBreak: '\n', whitespace: 'all'}); | ||
| const result = w(indent + value).substring(this._cursor).split('\n'); | ||
| return result; | ||
| } | ||
| return [value]; | ||
| } | ||
| /** | ||
| * Restore styles and codepages after drawing boxes or lines | ||
| */ | ||
| _restoreState() { | ||
| this.bold(this._state.bold); | ||
| this.italic(this._state.italic); | ||
| this.underline(this._state.underline); | ||
| this.invert(this._state.invert); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._state.codepage, | ||
| ]); | ||
| } | ||
| /** | ||
| * Get code page identifier for the specified code page and mapping | ||
| * | ||
| * @param {string} codepage Required code page | ||
| * @return {number} Identifier for the current printer according to the specified mapping | ||
| */ | ||
| _getCodepageIdentifier(codepage) { | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| return codepages[codepage]; | ||
| } | ||
| /** | ||
| * Initialize the printer | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| initialize() { | ||
| this._queue([ | ||
| 0x1b, 0x40, | ||
| ]); | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change the code page | ||
| * | ||
| * @param {string} codepage The codepage that we set the printer to | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| codepage(codepage) { | ||
| if (codepage === 'auto') { | ||
| this._codepage = codepage; | ||
| return this; | ||
| } | ||
| if (!CodepageEncoder.supports(codepage)) { | ||
| throw new Error('Unknown codepage'); | ||
| } | ||
| let codepages; | ||
| if (typeof this._options.codepageMapping == 'string') { | ||
| codepages = codepageMappings[this._options.codepageMapping]; | ||
| } else { | ||
| codepages = this._options.codepageMapping; | ||
| } | ||
| if (typeof codepages[codepage] !== 'undefined') { | ||
| this._codepage = codepage; | ||
| this._state.codepage = codepages[codepage]; | ||
| this._queue([ | ||
| 0x1b, 0x74, codepages[codepage], | ||
| ]); | ||
| } else { | ||
| throw new Error('Codepage not supported by printer'); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print text | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| text(value, wrap) { | ||
| const lines = this._wrap(value, wrap); | ||
| for (let l = 0; l < lines.length; l++) { | ||
| const bytes = this._encode(lines[l]); | ||
| this._queue([ | ||
| bytes, | ||
| ]); | ||
| this._cursor += (lines[l].length * this._state.width); | ||
| if (this._options.width && !this._embedded) { | ||
| this._cursor = this._cursor % this._options.width; | ||
| } | ||
| if (l < lines.length - 1) { | ||
| this.newline(); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print a newline | ||
| * | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| newline() { | ||
| this._flush(); | ||
| this._queue([ | ||
| 0x0a, 0x0d, | ||
| ]); | ||
| if (this._embedded) { | ||
| this._restoreState(); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Print text, followed by a newline | ||
| * | ||
| * @param {string} value Text that needs to be printed | ||
| * @param {number} wrap Wrap text after this many positions | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| line(value, wrap) { | ||
| this.text(value, wrap); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Underline text | ||
| * | ||
| * @param {boolean|number} value true to turn on underline, false to turn off, or 2 for double underline | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| underline(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.underline; | ||
| } | ||
| this._state.underline = value; | ||
| this._queue([ | ||
| 0x1b, 0x2d, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Italic text | ||
| * | ||
| * @param {boolean} value true to turn on italic, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| italic(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.italic; | ||
| } | ||
| this._state.italic = value; | ||
| this._queue([ | ||
| 0x1b, 0x34, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Bold text | ||
| * | ||
| * @param {boolean} value true to turn on bold, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| bold(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.bold; | ||
| } | ||
| this._state.bold = value; | ||
| this._queue([ | ||
| 0x1b, 0x45, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change width of text | ||
| * | ||
| * @param {number} width The width of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| width(width) { | ||
| if (typeof width === 'undefined') { | ||
| width = 1; | ||
| } | ||
| if (typeof width !== 'number') { | ||
| throw new Error('Width must be a number'); | ||
| } | ||
| if (width < 1 || width > 8) { | ||
| throw new Error('Width must be between 1 and 8'); | ||
| } | ||
| this._state.width = width; | ||
| this._queue([ | ||
| 0x1d, 0x21, (this._state.height - 1) | (this._state.width - 1) << 4, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change height of text | ||
| * | ||
| * @param {number} height The height of the text, 1 - 8 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| height(height) { | ||
| if (typeof height === 'undefined') { | ||
| height = 1; | ||
| } | ||
| if (typeof height !== 'number') { | ||
| throw new Error('Height must be a number'); | ||
| } | ||
| if (height < 1 || height > 8) { | ||
| throw new Error('Height must be between 1 and 8'); | ||
| } | ||
| this._state.height = height; | ||
| this._queue([ | ||
| 0x1d, 0x21, (this._state.height - 1) | (this._state.width - 1) << 4, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Invert text | ||
| * | ||
| * @param {boolean} value true to turn on white text on black, false to turn off | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| invert(value) { | ||
| if (typeof value === 'undefined') { | ||
| value = ! this._state.invert; | ||
| } | ||
| this._state.invert = value; | ||
| this._queue([ | ||
| 0x1d, 0x42, Number(value), | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change text size | ||
| * | ||
| * @param {string} value small or normal | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| size(value) { | ||
| if (value === 'small') { | ||
| value = 0x01; | ||
| } else { | ||
| value = 0x00; | ||
| } | ||
| this._queue([ | ||
| 0x1b, 0x4d, value, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Change text alignment | ||
| * | ||
| * @param {string} value left, center or right | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| align(value) { | ||
| const alignments = { | ||
| 'left': 0x00, | ||
| 'center': 0x01, | ||
| 'right': 0x02, | ||
| }; | ||
| if (value in alignments) { | ||
| this._state.align = value; | ||
| if (!this._embedded) { | ||
| this._queue([ | ||
| 0x1b, 0x61, alignments[value], | ||
| ]); | ||
| } | ||
| } else { | ||
| throw new Error('Unknown alignment'); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a table | ||
| * | ||
| * @param {array} columns The column definitions | ||
| * @param {array} data Array containing rows. Each row is an array containing cells. | ||
| * Each cell can be a string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| table(columns, data) { | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| for (let r = 0; r < data.length; r++) { | ||
| const lines = []; | ||
| let maxLines = 0; | ||
| for (let c = 0; c < columns.length; c++) { | ||
| const cell = []; | ||
| if (typeof data[r][c] === 'string') { | ||
| const w = linewrap(columns[c].width, {lineBreak: '\n'}); | ||
| const fragments = w(data[r][c]).split('\n'); | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| if (columns[c].align == 'right') { | ||
| cell[f] = this._encode(fragments[f].padStart(columns[c].width)); | ||
| } else { | ||
| cell[f] = this._encode(fragments[f].padEnd(columns[c].width)); | ||
| } | ||
| } | ||
| } | ||
| if (typeof data[r][c] === 'function') { | ||
| const columnEncoder = new EscPosEncoder(Object.assign({}, this._options, { | ||
| width: columns[c].width, | ||
| embedded: true, | ||
| })); | ||
| columnEncoder._codepage = this._codepage; | ||
| columnEncoder.align(columns[c].align); | ||
| data[r][c](columnEncoder); | ||
| const encoded = columnEncoder.encode(); | ||
| let fragment = []; | ||
| for (let e = 0; e < encoded.byteLength; e++) { | ||
| if (e < encoded.byteLength - 1) { | ||
| if (encoded[e] === 0x0a && encoded[e + 1] === 0x0d) { | ||
| cell.push(fragment); | ||
| fragment = []; | ||
| e++; | ||
| continue; | ||
| } | ||
| } | ||
| fragment.push(encoded[e]); | ||
| } | ||
| if (fragment.length) { | ||
| cell.push(fragment); | ||
| } | ||
| } | ||
| maxLines = Math.max(maxLines, cell.length); | ||
| lines[c] = cell; | ||
| } | ||
| for (let c = 0; c < columns.length; c++) { | ||
| if (lines[c].length < maxLines) { | ||
| for (let p = lines[c].length; p < maxLines; p++) { | ||
| let verticalAlign = 'top'; | ||
| if (typeof columns[c].verticalAlign !== 'undefined') { | ||
| verticalAlign = columns[c].verticalAlign; | ||
| } | ||
| if (verticalAlign == 'bottom') { | ||
| lines[c].unshift((new Array(columns[c].width)).fill(0x20)); | ||
| } else { | ||
| lines[c].push((new Array(columns[c].width)).fill(0x20)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| for (let l = 0; l < maxLines; l++) { | ||
| for (let c = 0; c < columns.length; c++) { | ||
| if (typeof columns[c].marginLeft !== 'undefined') { | ||
| this.raw((new Array(columns[c].marginLeft)).fill(0x20)); | ||
| } | ||
| this.raw(lines[c][l]); | ||
| if (typeof columns[c].marginRight !== 'undefined') { | ||
| this.raw((new Array(columns[c].marginRight)).fill(0x20)); | ||
| } | ||
| } | ||
| this.newline(); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a horizontal rule | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the line, either single or double | ||
| * - width: The width of the line, by default the width of the paper | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| rule(options) { | ||
| options = Object.assign({ | ||
| style: 'single', | ||
| width: this._options.width || 10, | ||
| }, options || {}); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| (new Array(options.width)).fill(options.style === 'double' ? 0xcd : 0xc4), | ||
| ]); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._state.codepage, | ||
| ]); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Insert a horizontal rule | ||
| * | ||
| * @param {object} options And object with the following properties: | ||
| * - style: The style of the border, either single or double | ||
| * - width: The width of the box, by default the width of the paper, if specified | ||
| * - marginLeft: Space between the left border and the left side of the paper | ||
| * - marginRight: Space between the right border and the right side of the paper | ||
| * - paddingLeft: Space between the contents and the left border of the box | ||
| * - paddingRight: Space between the contents and the right border of the box | ||
| * @param {string|function} contents A string value, or a callback function. | ||
| * The first parameter of the callback is the encoder object on | ||
| * which the function can call its methods. | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| box(options, contents) { | ||
| options = Object.assign({ | ||
| style: 'single', | ||
| width: this._options.width || 30, | ||
| marginLeft: 0, | ||
| marginRight: 0, | ||
| paddingLeft: 0, | ||
| paddingRight: 0, | ||
| }, options || {}); | ||
| let elements; | ||
| if (options.style == 'double') { | ||
| elements = [0xc9, 0xbb, 0xc8, 0xbc, 0xcd, 0xba]; // ╔╗╚╝═║ | ||
| } else { | ||
| elements = [0xda, 0xbf, 0xc0, 0xd9, 0xc4, 0xb3]; // ┌┐└┘─│ | ||
| } | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| this._restoreState(); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| ]); | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[0], | ||
| new Array(options.width - 2).fill(elements[4]), | ||
| elements[1], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this.newline(); | ||
| const cell = []; | ||
| if (typeof contents === 'string') { | ||
| const w = linewrap(options.width - 2 - options.paddingLeft - options.paddingRight, {lineBreak: '\n'}); | ||
| const fragments = w(contents).split('\n'); | ||
| for (let f = 0; f < fragments.length; f++) { | ||
| if (options.align == 'right') { | ||
| cell[f] = this._encode(fragments[f].padStart(options.width - 2 - options.paddingLeft - options.paddingRight)); | ||
| } else { | ||
| cell[f] = this._encode(fragments[f].padEnd(options.width - 2 - options.paddingLeft - options.paddingRight)); | ||
| } | ||
| } | ||
| } | ||
| if (typeof contents === 'function') { | ||
| const columnEncoder = new EscPosEncoder(Object.assign({}, this._options, { | ||
| width: options.width - 2 - options.paddingLeft - options.paddingRight, | ||
| embedded: true, | ||
| })); | ||
| columnEncoder._codepage = this._codepage; | ||
| columnEncoder.align(options.align); | ||
| contents(columnEncoder); | ||
| const encoded = columnEncoder.encode(); | ||
| let fragment = []; | ||
| for (let e = 0; e < encoded.byteLength; e++) { | ||
| if (e < encoded.byteLength - 1) { | ||
| if (encoded[e] === 0x0a && encoded[e + 1] === 0x0d) { | ||
| cell.push(fragment); | ||
| fragment = []; | ||
| e++; | ||
| continue; | ||
| } | ||
| } | ||
| fragment.push(encoded[e]); | ||
| } | ||
| if (fragment.length) { | ||
| cell.push(fragment); | ||
| } | ||
| } | ||
| for (let c = 0; c < cell.length; c++) { | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[5], | ||
| new Array(options.paddingLeft).fill(0x20), | ||
| ]); | ||
| this._queue([ | ||
| cell[c], | ||
| ]); | ||
| this._restoreState(); | ||
| this._queue([ | ||
| 0x1b, 0x74, this._getCodepageIdentifier('cp437'), | ||
| ]); | ||
| this._queue([ | ||
| new Array(options.paddingRight).fill(0x20), | ||
| elements[5], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this.newline(); | ||
| } | ||
| this._queue([ | ||
| new Array(options.marginLeft).fill(0x20), | ||
| elements[2], | ||
| new Array(options.width - 2).fill(elements[4]), | ||
| elements[3], | ||
| new Array(options.marginRight).fill(0x20), | ||
| ]); | ||
| this._restoreState(); | ||
| this.newline(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Barcode | ||
| * | ||
| * @param {string} value the value of the barcode | ||
| * @param {string} symbology the type of the barcode | ||
| * @param {number} height height of the barcode | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| barcode(value, symbology, height) { | ||
| if (this._embedded) { | ||
| throw new Error('Barcodes are not supported in table cells or boxes'); | ||
| } | ||
| const symbologies = { | ||
| 'upca': 0x00, | ||
| 'upce': 0x01, | ||
| 'ean13': 0x02, | ||
| 'ean8': 0x03, | ||
| 'code39': 0x04, | ||
| 'coda39': 0x04, /* typo, leave here for backwards compatibility */ | ||
| 'itf': 0x05, | ||
| 'codabar': 0x06, | ||
| 'code93': 0x48, | ||
| 'code128': 0x49, | ||
| 'gs1-128': 0x50, | ||
| 'gs1-databar-omni': 0x51, | ||
| 'gs1-databar-truncated': 0x52, | ||
| 'gs1-databar-limited': 0x53, | ||
| 'gs1-databar-expanded': 0x54, | ||
| 'code128-auto': 0x55, | ||
| }; | ||
| if (symbology in symbologies) { | ||
| const bytes = CodepageEncoder.encode('ascii', value); | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x68, height, | ||
| 0x1d, 0x77, symbology === 'code39' ? 0x02 : 0x03, | ||
| ]); | ||
| if (symbology == 'code128' && bytes[0] !== 0x7b) { | ||
| /* Not yet encodeded Code 128, assume data is Code B, which is similar to ASCII without control chars */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes.length + 2, | ||
| 0x7b, 0x42, | ||
| bytes, | ||
| ]); | ||
| } else if (symbologies[symbology] > 0x40) { | ||
| /* Function B symbologies */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes.length, | ||
| bytes, | ||
| ]); | ||
| } else { | ||
| /* Function A symbologies */ | ||
| this._queue([ | ||
| 0x1d, 0x6b, symbologies[symbology], | ||
| bytes, | ||
| 0x00, | ||
| ]); | ||
| } | ||
| } else { | ||
| throw new Error('Symbology not supported by printer'); | ||
| } | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * QR code | ||
| * | ||
| * @param {string} value the value of the qr code | ||
| * @param {number} model model of the qrcode, either 1 or 2 | ||
| * @param {number} size size of the qrcode, a value between 1 and 8 | ||
| * @param {string} errorlevel the amount of error correction used, either 'l', 'm', 'q', 'h' | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| qrcode(value, model, size, errorlevel) { | ||
| if (this._embedded) { | ||
| throw new Error('QR codes are not supported in table cells or boxes'); | ||
| } | ||
| /* Force printing the print buffer and moving to a new line */ | ||
| this._queue([ | ||
| 0x0a, | ||
| ]); | ||
| /* Model */ | ||
| const models = { | ||
| 1: 0x31, | ||
| 2: 0x32, | ||
| }; | ||
| if (typeof model === 'undefined') { | ||
| model = 2; | ||
| } | ||
| if (model in models) { | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x04, 0x00, 0x31, 0x41, models[model], 0x00, | ||
| ]); | ||
| } else { | ||
| throw new Error('Model must be 1 or 2'); | ||
| } | ||
| /* Size */ | ||
| if (typeof size === 'undefined') { | ||
| size = 6; | ||
| } | ||
| if (typeof size !== 'number') { | ||
| throw new Error('Size must be a number'); | ||
| } | ||
| if (size < 1 || size > 8) { | ||
| throw new Error('Size must be between 1 and 8'); | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, size, | ||
| ]); | ||
| /* Error level */ | ||
| const errorlevels = { | ||
| 'l': 0x30, | ||
| 'm': 0x31, | ||
| 'q': 0x32, | ||
| 'h': 0x33, | ||
| }; | ||
| if (typeof errorlevel === 'undefined') { | ||
| errorlevel = 'm'; | ||
| } | ||
| if (errorlevel in errorlevels) { | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x45, errorlevels[errorlevel], | ||
| ]); | ||
| } else { | ||
| throw new Error('Error level must be l, m, q or h'); | ||
| } | ||
| /* Data */ | ||
| const bytes = CodepageEncoder.encode('iso88591', value); | ||
| const length = bytes.length + 3; | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, length % 0xff, length / 0xff, 0x31, 0x50, 0x30, bytes, | ||
| ]); | ||
| /* Print QR code */ | ||
| this._queue([ | ||
| 0x1d, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30, | ||
| ]); | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Image | ||
| * | ||
| * @param {object} element an element, like a canvas or image that needs to be printed | ||
| * @param {number} width width of the image on the printer | ||
| * @param {number} height height of the image on the printer | ||
| * @param {string} algorithm the dithering algorithm for making the image black and white | ||
| * @param {number} threshold threshold for the dithering algorithm | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| image(element, width, height, algorithm, threshold) { | ||
| if (this._embedded) { | ||
| throw new Error('Images are not supported in table cells or boxes'); | ||
| } | ||
| if (width % 8 !== 0) { | ||
| throw new Error('Width must be a multiple of 8'); | ||
| } | ||
| if (height % 8 !== 0) { | ||
| throw new Error('Height must be a multiple of 8'); | ||
| } | ||
| if (typeof algorithm === 'undefined') { | ||
| algorithm = 'threshold'; | ||
| } | ||
| if (typeof threshold === 'undefined') { | ||
| threshold = 128; | ||
| } | ||
| const canvas = createCanvas(width, height); | ||
| const context = canvas.getContext('2d'); | ||
| context.drawImage(element, 0, 0, width, height); | ||
| let image = context.getImageData(0, 0, width, height); | ||
| image = Flatten.flatten(image, [0xff, 0xff, 0xff]); | ||
| switch (algorithm) { | ||
| case 'threshold': image = Dither.threshold(image, threshold); break; | ||
| case 'bayer': image = Dither.bayer(image, threshold); break; | ||
| case 'floydsteinberg': image = Dither.floydsteinberg(image); break; | ||
| case 'atkinson': image = Dither.atkinson(image); break; | ||
| } | ||
| const getPixel = (x, y) => x < width && y < height ? (image.data[((width * y) + x) * 4] > 0 ? 0 : 1) : 0; | ||
| const getColumnData = (width, height) => { | ||
| const data = []; | ||
| for (let s = 0; s < Math.ceil(height / 24); s++) { | ||
| const bytes = new Uint8Array(width * 3); | ||
| for (let x = 0; x < width; x++) { | ||
| for (let c = 0; c < 3; c++) { | ||
| for (let b = 0; b < 8; b++) { | ||
| bytes[(x * 3) + c] |= getPixel(x, (s * 24) + b + (8 * c)) << (7 - b); | ||
| } | ||
| } | ||
| } | ||
| data.push(bytes); | ||
| } | ||
| return data; | ||
| }; | ||
| const getRowData = (width, height) => { | ||
| const bytes = new Uint8Array((width * height) >> 3); | ||
| for (let y = 0; y < height; y++) { | ||
| for (let x = 0; x < width; x = x + 8) { | ||
| for (let b = 0; b < 8; b++) { | ||
| bytes[(y * (width >> 3)) + (x >> 3)] |= getPixel(x + b, y) << (7 - b); | ||
| } | ||
| } | ||
| } | ||
| return bytes; | ||
| }; | ||
| if (this._cursor != 0) { | ||
| this.newline(); | ||
| } | ||
| /* Encode images with ESC * */ | ||
| if (this._options.imageMode == 'column') { | ||
| this._queue([ | ||
| 0x1b, 0x33, 0x24, | ||
| ]); | ||
| getColumnData(width, height).forEach((bytes) => { | ||
| this._queue([ | ||
| 0x1b, 0x2a, 0x21, | ||
| (width) & 0xff, (((width) >> 8) & 0xff), | ||
| bytes, | ||
| 0x0a, | ||
| ]); | ||
| }); | ||
| this._queue([ | ||
| 0x1b, 0x32, | ||
| ]); | ||
| } | ||
| /* Encode images with GS v */ | ||
| if (this._options.imageMode == 'raster') { | ||
| this._queue([ | ||
| 0x1d, 0x76, 0x30, 0x00, | ||
| (width >> 3) & 0xff, (((width >> 3) >> 8) & 0xff), | ||
| height & 0xff, ((height >> 8) & 0xff), | ||
| getRowData(width, height), | ||
| ]); | ||
| } | ||
| this._flush(); | ||
| return this; | ||
| } | ||
| /** | ||
| * Cut paper | ||
| * | ||
| * @param {string} value full or partial. When not specified a full cut will be assumed | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| cut(value) { | ||
| if (this._embedded) { | ||
| throw new Error('Cut is not supported in table cells or boxes'); | ||
| } | ||
| let data = 0x00; | ||
| if (value == 'partial') { | ||
| data = 0x01; | ||
| } | ||
| this._queue([ | ||
| 0x1d, 0x56, data, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Pulse | ||
| * | ||
| * @param {number} device 0 or 1 for on which pin the device is connected, default of 0 | ||
| * @param {number} on Time the pulse is on in milliseconds, default of 100 | ||
| * @param {number} off Time the pulse is off in milliseconds, default of 500 | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| pulse(device, on, off) { | ||
| if (this._embedded) { | ||
| throw new Error('Pulse is not supported in table cells or boxes'); | ||
| } | ||
| if (typeof device === 'undefined') { | ||
| device = 0; | ||
| } | ||
| if (typeof on === 'undefined') { | ||
| on = 100; | ||
| } | ||
| if (typeof off === 'undefined') { | ||
| off = 500; | ||
| } | ||
| on = Math.min(500, Math.round(on / 2)); | ||
| off = Math.min(500, Math.round(off / 2)); | ||
| this._queue([ | ||
| 0x1b, 0x70, device ? 1 : 0, on & 0xff, off & 0xff, | ||
| ]); | ||
| return this; | ||
| } | ||
| /** | ||
| * Add raw printer commands | ||
| * | ||
| * @param {array} data raw bytes to be included | ||
| * @return {object} Return the object, for easy chaining commands | ||
| * | ||
| */ | ||
| raw(data) { | ||
| this._queue(data); | ||
| return this; | ||
| } | ||
| /** | ||
| * Encode all previous commands | ||
| * | ||
| * @return {Uint8Array} Return the encoded bytes | ||
| * | ||
| */ | ||
| encode() { | ||
| this._flush(); | ||
| let length = 0; | ||
| this._buffer.forEach((item) => { | ||
| if (typeof item === 'number') { | ||
| length++; | ||
| } else { | ||
| length += item.length; | ||
| } | ||
| }); | ||
| const result = new Uint8Array(length); | ||
| let index = 0; | ||
| this._buffer.forEach((item) => { | ||
| if (typeof item === 'number') { | ||
| result[index] = item; | ||
| index++; | ||
| } else { | ||
| result.set(item, index); | ||
| index += item.length; | ||
| } | ||
| }); | ||
| this._reset(); | ||
| return result; | ||
| } | ||
| } | ||
| module.exports = EscPosEncoder; |
| const EscPosEncoder = require ('../src/esc-pos-encoder'); | ||
| const { createCanvas } = require('canvas'); | ||
| const chai = require('chai'); | ||
| const assert = chai.assert; | ||
| const expect = chai.expect; | ||
| const should = chai.should(); | ||
| describe('EscPosEncoder', function() { | ||
| let encoder = new EscPosEncoder(); | ||
| let rasterEncoder = new EscPosEncoder({ imageMode: 'raster' }); | ||
| describe('text(hello)', function () { | ||
| let result = encoder.text('hello').encode(); | ||
| it('should be [ 104, 101, 108, 108, 111 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 104, 101, 108, 108, 111 ]), result); | ||
| }); | ||
| }); | ||
| describe('text(hello).newline()', function () { | ||
| let result = encoder.text('hello').newline().encode(); | ||
| it('should be [ 104, 101, 108, 108, 111, 10, 13 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 104, 101, 108, 108, 111, 10, 13 ]), result); | ||
| }); | ||
| }); | ||
| describe('line(hello)', function () { | ||
| let result = encoder.line('hello').encode(); | ||
| it('should be [ 104, 101, 108, 108, 111, 10, 13 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 104, 101, 108, 108, 111, 10, 13 ]), result); | ||
| }); | ||
| }); | ||
| describe('text(héllo) - é -> ?', function () { | ||
| let result = encoder.text('héllo').encode(); | ||
| it('should be [ 104, 63, 108, 108, 111 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 104, 63, 108, 108, 111 ]), result); | ||
| }); | ||
| }); | ||
| describe('codepage(cp437).text(héllo) - é -> 130', function () { | ||
| let result = encoder.codepage('cp437').text('héllo').encode(); | ||
| it('should be [ 27, 116, 0, 104, 130, 108, 108, 111 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 116, 0, 104, 130, 108, 108, 111 ]), result); | ||
| }); | ||
| }); | ||
| describe('codepage(windows1252).text(héllo) - é -> 233', function () { | ||
| let result = encoder.codepage('windows1252').text('héllo').encode(); | ||
| it('should be [ 27, 116, 16, 104, 233, 108, 108, 111 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 116, 16, 104, 233, 108, 108, 111 ]), result); | ||
| }); | ||
| }); | ||
| describe('codepage(unknown).text(héllo)', function () { | ||
| it('should throw an "Unknown codepage" error', function () { | ||
| expect(function(){ | ||
| let result = encoder.codepage('unknown').text('héllo').encode(); | ||
| }).to.throw('Unknown codepage'); | ||
| }); | ||
| }); | ||
| describe('bold(true).text(hello).bold(false)', function () { | ||
| let result = encoder.bold(true).text('hello').bold(false).encode(); | ||
| it('should be [ 27, 69, 1, ..., 27, 69, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 69, 1, 104, 101, 108, 108, 111, 27, 69, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('bold().text(hello).bold()', function () { | ||
| let result = encoder.bold().text('hello').bold().encode(); | ||
| it('should be [ 27, 69, 1, ..., 27, 69, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 69, 1, 104, 101, 108, 108, 111, 27, 69, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('italic().text(hello).italic()', function () { | ||
| let result = encoder.italic().text('hello').italic().encode(); | ||
| it('should be [ 27, 69, 1, ..., 27, 69, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 52, 1, 104, 101, 108, 108, 111, 27, 52, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('underline(true).text(hello).underline(false)', function () { | ||
| let result = encoder.underline(true).text('hello').underline(false).encode(); | ||
| it('should be [ 27, 45, 1, ..., 27, 45, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 45, 1, 104, 101, 108, 108, 111, 27, 45, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('underline().text(hello).underline()', function () { | ||
| let result = encoder.underline().text('hello').underline().encode(); | ||
| it('should be [ 27, 45, 1, ..., 27, 45, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 45, 1, 104, 101, 108, 108, 111, 27, 45, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('invert().text(hello).invert()', function () { | ||
| let result = encoder.invert().text('hello').invert().encode(); | ||
| it('should be [ 29, 66, 1, ..., 29, 66, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 66, 1, 104, 101, 108, 108, 111, 29, 66, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('width(2).text(hello).width(1)', function () { | ||
| let result = encoder.width(2).text('hello').width(1).encode(); | ||
| it('should be [ 29, 33, 16, ..., 29, 33, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 33, 16, 104, 101, 108, 108, 111, 29, 33, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('height(2).text(hello).height(1)', function () { | ||
| let result = encoder.height(2).text('hello').height(1).encode(); | ||
| it('should be [ 29, 33, 1, ..., 29, 33, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 33, 1, 104, 101, 108, 108, 111, 29, 33, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('width(2).height(2).text(hello).width(1).height(1)', function () { | ||
| let result = encoder.width(2).height(2).text('hello').width(1).height(1).encode(); | ||
| it('should be [ 29, 33, 16, 29, 33, 17, ..., 29, 33, 1, 29, 33, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 33, 16, 29, 33, 17, 104, 101, 108, 108, 111, 29, 33, 1, 29, 33, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('align(left).line(hello)', function () { | ||
| let result = encoder.align('left').line('hello').encode(); | ||
| it('should be [ 27, 97, 0, ..., 10, 13 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 97, 0, 104, 101, 108, 108, 111, 10, 13 ]), result); | ||
| }); | ||
| }); | ||
| describe('align(center).line(hello)', function () { | ||
| let result = encoder.align('center').line('hello').encode(); | ||
| it('should be [ 27, 97, 1, ..., 10, 13 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 97, 1, 104, 101, 108, 108, 111, 10, 13 ]), result); | ||
| }); | ||
| }); | ||
| describe('align(right).line(hello)', function () { | ||
| let result = encoder.align('right').line('hello').encode(); | ||
| it('should be [ 27, 97, 2, ..., 10, 13 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 97, 2, 104, 101, 108, 108, 111, 10, 13 ]), result); | ||
| }); | ||
| }); | ||
| describe('qrcode(https://nielsleenheer.com)', function () { | ||
| let result = encoder.qrcode('https://nielsleenheer.com').encode(); | ||
| it('should be [ 10, 29, 40, 107, 4, 0, 49, 65, 50, 0, 29, 40, 107, 3, 0, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 10, 29, 40, 107, 4, 0, 49, 65, 50, 0, 29, 40, 107, 3, 0, 49, 67, 6, 29, 40, 107, 3, 0, 49, 69, 49, 29, 40, 107, 28, 0, 49, 80, 48, 104, 116, 116, 112, 115, 58, 47, 47, 110, 105, 101, 108, 115, 108, 101, 101, 110, 104, 101, 101, 114, 46, 99, 111, 109, 29, 40, 107, 3, 0, 49, 81, 48 ]), result); | ||
| }); | ||
| }); | ||
| describe('qrcode(https://nielsleenheer.com, 1, 8, h)', function () { | ||
| let result = encoder.qrcode('https://nielsleenheer.com', 1, 8, 'h').encode(); | ||
| it('should be [ 10, 29, 40, 107, 4, 0, 49, 65, 49, 0, 29, 40, 107, 3, 0, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 10, 29, 40, 107, 4, 0, 49, 65, 49, 0, 29, 40, 107, 3, 0, 49, 67, 8, 29, 40, 107, 3, 0, 49, 69, 51, 29, 40, 107, 28, 0, 49, 80, 48, 104, 116, 116, 112, 115, 58, 47, 47, 110, 105, 101, 108, 115, 108, 101, 101, 110, 104, 101, 101, 114, 46, 99, 111, 109, 29, 40, 107, 3, 0, 49, 81, 48 ]), result); | ||
| }); | ||
| }); | ||
| describe('barcode(3130630574613, ean13, 60)', function () { | ||
| let result = encoder.barcode('3130630574613', 'ean13', 60).encode(); | ||
| it('should be [ 29, 104, 60, 29, 119, 3, 29, 107, 2, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 104, 60, 29, 119, 3, 29, 107, 2, 51, 49, 51, 48, 54, 51, 48, 53, 55, 52, 54, 49, 51, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('barcode(CODE128, code128, 60)', function () { | ||
| let result = encoder.barcode('CODE128', 'code128', 60).encode(); | ||
| it('should be [ 29, 104, 60, 29, 119, 3, 29, 107, 73, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 104, 60, 29, 119, 3, 29, 107, 73, 9, 123, 66, 67, 79, 68, 69, 49, 50, 56 ]), result); | ||
| }); | ||
| }); | ||
| describe('barcode({ACODE128, code128, 60)', function () { | ||
| let result = encoder.barcode('{ACODE128', 'code128', 60).encode(); | ||
| it('should be [ 29, 104, 60, 29, 119, 3, 29, 107, 73, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 104, 60, 29, 119, 3, 29, 107, 73, 9, 123, 65, 67, 79, 68, 69, 49, 50, 56 ]), result); | ||
| }); | ||
| }); | ||
| describe('barcode({BCODE128, code128, 60)', function () { | ||
| let result = encoder.barcode('{BCODE128', 'code128', 60).encode(); | ||
| it('should be [ 29, 104, 60, 29, 119, 3, 29, 107, 73, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 104, 60, 29, 119, 3, 29, 107, 73, 9, 123, 66, 67, 79, 68, 69, 49, 50, 56 ]), result); | ||
| }); | ||
| }); | ||
| describe('barcode({C2Uc#, code128, 60)', function () { | ||
| let result = encoder.barcode('{C2Uc#', 'code128', 60).encode(); | ||
| it('should be [ 29, 104, 60, 29, 119, 3, 29, 107, 73, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 104, 60, 29, 119, 3, 29, 107, 73, 6, 123, 67, 50, 85, 99, 35 ]), result); | ||
| }); | ||
| }); | ||
| describe('image(canvas, 8, 8) - with a black pixel at 0,0 (legacy)', function () { | ||
| let canvas = createCanvas(8, 8); | ||
| let context = canvas.getContext('2d'); | ||
| context.fillStyle = 'rgba(0, 0, 0, 1)'; | ||
| context.fillRect( 0, 0, 1, 1 ); | ||
| let result = rasterEncoder.image(canvas, 8, 8).encode(); | ||
| it('should be [ 29, 118, 48, 0, 1, 0, 8, 0, 128, 0, 0, 0, 0, 0, 0, 0 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 118, 48, 0, 1, 0, 8, 0, 128, 0, 0, 0, 0, 0, 0, 0 ]), result); | ||
| }); | ||
| }); | ||
| describe('image(canvas, 8, 8) - with a black pixel at 0,0', function () { | ||
| let canvas = createCanvas(8, 8); | ||
| let context = canvas.getContext('2d'); | ||
| context.fillStyle = 'rgba(0, 0, 0, 1)'; | ||
| context.fillRect( 0, 0, 1, 1 ); | ||
| let result = encoder.image(canvas, 8, 8).encode(); | ||
| it('should be [ 27, 51, 36, 27, 42, 33, 8, 0, 128, 0, 0, 0, 0, ... ]', function () { | ||
| assert.deepEqual(new Uint8Array([27, 51, 36, 27, 42, 33, 8, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 27, 50]), result); | ||
| }); | ||
| }); | ||
| describe('pulse()', function () { | ||
| let result = encoder.pulse().encode(); | ||
| it('should be [ 27, 112, 0, 50, 250 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 27, 112, 0, 50, 250 ]), result); | ||
| }); | ||
| }); | ||
| describe('cut()', function () { | ||
| let result = encoder.cut().encode(); | ||
| it('should be [ 29, 86, 00 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 86, 00 ]), result); | ||
| }); | ||
| }); | ||
| describe('cut(full)', function () { | ||
| let result = encoder.cut('full').encode(); | ||
| it('should be [ 29, 86, 00 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 86, 00 ]), result); | ||
| }); | ||
| }); | ||
| describe('cut(partial)', function () { | ||
| let result = encoder.cut('partial').encode(); | ||
| it('should be [ 29, 86, 01 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 29, 86, 01 ]), result); | ||
| }); | ||
| }); | ||
| describe('raw([ 0x1c, 0x2e ])', function () { | ||
| let result = encoder.raw([ 0x1c, 0x2e ]).encode(); | ||
| it('should be [ 28, 46 ]', function () { | ||
| assert.deepEqual(new Uint8Array([ 28, 46 ]), result); | ||
| }); | ||
| }); | ||
| describe('codepage(auto).text(héψжł)', function () { | ||
| let result = encoder.codepage('auto').text('héψжł').encode(); | ||
| it('should be [27, 116, 0, 104, 130, 27, 116, 38, 246, 27, 116, 34, 233, 27, 116, 18, 136]', function () { | ||
| assert.deepEqual(new Uint8Array([27, 116, 0, 104, 130, 27, 116, 38, 246, 27, 116, 34, 233, 27, 116, 18, 136]), result); | ||
| }); | ||
| }); | ||
| }); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
182629
47.12%2602
64.79%603
12.92%Yes
NaN7
-12.5%2
100%1
Infinity%+ Added
- Removed
Updated
Updated