├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .github
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── npm-publish.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── examples
├── package.json
├── src
│ ├── basic.ts
│ ├── network.ts
│ ├── printBarCode.ts
│ ├── printImage.ts
│ ├── printTable.ts
│ └── templates.ts
├── tsconfig.json
└── yarn.lock
├── package.json
├── resources
└── ESCPOS_Command_Manual.pdf
├── src
├── buffer-builder.ts
├── command.ts
├── escpos.ts
├── image.ts
├── index.ts
├── node-factory.ts
├── nodes
│ ├── align-node.ts
│ ├── barcode-node.ts
│ ├── bold-node.ts
│ ├── break-line-node.ts
│ ├── document-node.ts
│ ├── image-node.ts
│ ├── line-feed-node.ts
│ ├── open-cash-drawer-node.ts
│ ├── paper-cut-node.ts
│ ├── print-mode.ts
│ ├── qrcode-node.ts
│ ├── small-node.ts
│ ├── text-line-node.ts
│ ├── text-node.ts
│ ├── underline-node.ts
│ └── white-mode-node.ts
├── template-parser.ts
├── xml-node.ts
└── xml-parser.ts
├── tsconfig.build.json
├── tsconfig.json
├── tslint.json
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs
2 | # editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 2
9 |
10 | # We recommend you to keep these unchanged
11 | end_of_line = lf
12 | charset = utf-8
13 | trim_trailing_whitespace = true
14 | insert_final_newline = true
15 |
16 | [*.md]
17 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/node_modules
2 | **/lib
3 | eslint_report.json
4 | .nyc_output
5 | coverage
6 | .vscode
7 | jest.config.js
8 | *.d.ts
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "@typescript-eslint/parser",
3 | "extends": [
4 | "plugin:@typescript-eslint/recommended",
5 | "prettier",
6 | "prettier/@typescript-eslint"
7 | ],
8 | "plugins": ["@typescript-eslint"],
9 | "rules": {
10 | "no-trailing-spaces": "warn",
11 | "comma-dangle": "off",
12 | "quotes": [
13 | "error",
14 | "single",
15 | {
16 | "avoidEscape": true
17 | }
18 | ],
19 | "semi": "warn",
20 | "@typescript-eslint/no-var-requires": "off",
21 | "@typescript-eslint/ban-types": "off",
22 | "@typescript-eslint/explicit-module-boundary-types": "off",
23 | "@typescript-eslint/ban-ts-ignore": "off",
24 | "@typescript-eslint/camelcase": "off"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 |
4 | ## Related Issues
5 |
6 |
7 |
8 |
9 | Issue: #XXX
10 |
11 | ## How Has This Been Tested
12 |
13 |
14 |
15 |
16 | ## Types of changes
17 |
18 |
19 | - [ ] Bug fix (non-breaking change which fixes an issue)
20 | - [ ] New feature (non-breaking change which adds functionality)
21 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
22 |
23 | ## Checklist
24 |
25 |
26 |
27 | - [ ] My code follows the code style of this project.
28 | - [ ] My change requires a change to the documentation.
29 | - [ ] I have updated the documentation accordingly.
30 | - [ ] I have added tests to cover my changes.
31 | - [ ] All new and existing tests passed.
32 |
33 | ## Screenshots (if appropriate)
34 |
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | name: npm-publish
2 | on:
3 | push:
4 | tags:
5 | - 'v*.*.*'
6 |
7 | jobs:
8 | npm-publish:
9 | name: npm-publish
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout repository
13 | uses: actions/checkout@v2
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: 12
17 | registry-url: https://registry.npmjs.org/
18 | - name: Install Node Dependencies
19 | run: yarn install; cd examples; yarn install; cd ..
20 | - name: Build packages
21 | run: yarn build
22 | env:
23 | CI: "TRUE"
24 | - run: npm publish --access public
25 | env:
26 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}}
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/lib
2 | **/node_modules
3 | coverage/*
4 | **/dist
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | **/node_modules
2 | **/build
3 | **/dist
4 | **/.github
5 | eslint_report.json
6 | .nyc_output
7 | coverage
8 | .vscode
9 | **/.jest
10 | .jest
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "singleQuote": true,
4 | "semi": true,
5 | "tabWidth": 2,
6 | "useTabs": false,
7 | "arrowParens": "avoid",
8 | "endOfLine": "auto",
9 | "bracketSpacing": true
10 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/.git": true,
4 | "**/.github": true,
5 | "**/.hg": true,
6 | "**/CVS": true,
7 | "**/.DS_Store": true,
8 | "**/node_modules": true,
9 | "**/coverage": true,
10 | "**/lib": true,
11 | "**/yarn.lock": true,
12 | "**/dist": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Originally forked from [here](https://github.com/ingoncalves/escpos-xml)
2 |
3 | # ESC/POS XML
4 |
5 | Cross platform JavaScript library that implements the thermal printer ESC / POS protocol and provides an XML interface for preparing templates for printing.
6 |
7 | ## Features
8 |
9 | - [x] Text
10 | - [x] Text line
11 | - [x] Feed line
12 | - [x] Bold text
13 | - [x] Underline text
14 | - [x] Font size
15 | - [x] Small mode
16 | - [x] White mode
17 | - [x] Align
18 | - [x] Barcode
19 | - [x] QRcode
20 | - [x] Paper cut node
21 | - [x] Image (base64) (png only)
22 | - [x] XML with mustache
23 |
24 |
25 | ## Tested manually on following environments or platforms
26 |
27 | - [x] React Native (Android)
28 | - [x] React Native (iOS)
29 | - [x] React Native Web
30 | - [x] Server side (NodeJs)
31 | - [x] Desktop applications (nwjs & electron)
32 | - [x] Other node environment (terminal)
33 |
34 |
35 | ## Installation
36 |
37 | ```bash
38 | yarn add @tillpos/xml-escpos-helper
39 | ```
40 |
41 | ## Examples
42 |
43 | ### With an XML template + plain object input (regular text).
44 |
45 | ```ts
46 |
47 | import { EscPos } from '@tillpos/xml-escpos-helper';
48 |
49 | // store this template somewhere `s3` or as `static asset` based on your preference
50 | const template = `
51 |
52 |
53 |
54 |
55 | {{title}}
56 |
57 |
58 |
59 | {{#thankyouNote}}
60 |
61 | {{{thankyouNote}}}
62 |
63 |
64 |
65 |
66 |
67 |
68 | `;
69 |
70 | const input = {
71 | title: 'Sample',
72 | thankyouNote: 'Welcome...!'
73 | };
74 |
75 | const buffer = EscPos.getBufferFromTemplate(template, input);
76 | // send this buffer to a stream (eg.: bluetooth or wifi)
77 |
78 | ```
79 |
80 | ### With an XML template + png image (base64)
81 |
82 | ```ts
83 | const template = `
84 |
85 |
86 |
87 | {{title}}
88 |
89 |
90 |
91 | {{base64PngImage}}
92 |
93 |
94 | `;
95 |
96 | const input = {
97 | title: 'PNG - base64',
98 | base64PngImage: `data:image/png;base64,iVBORw0KGgoAAA+P/AaNn2GPEMgEFAAAAAElFTkSuQmCC`
99 | };
100 |
101 | const buffer = EscPos.getBufferFromTemplate(template, input);
102 | ```
103 |
104 | ---
105 |
106 | ## TODO
107 |
108 | - [ ] Font styles (font family)
109 | - [ ] Image bitmap conversion improvements
110 | - [ ] jpeg support
111 | - [ ] Add example apps to repo
112 | - [ ] Removed uglify for some reason, need to bring it back
113 | - [ ] Improve image rendering
114 |
115 | ## Common issues
116 |
117 | - If there is any delay you observe while printing with this library it is mostly due to image manipulations (try without image :mask: )
118 |
119 |
120 | ## Useful links / resources
121 |
122 | - [ESC / POS Commands manual](./resources/ESCPOS_Command_Manual.pdf)
123 | - A [blog post](https://www.visuality.pl/posts/thermal-printer-protocols-for-image-and-text#:~:text=How%20can%20we%20print%20an,command%20language%20of%20thermal%20printers) explaiing about printing images with ESCPOS
124 | - Similar library for serverside - [node-escpos](https://github.com/song940/node-escpos).
125 |
126 | > Limitations on the react-native framework
127 |
128 | - [FileReader.readAsArrayBuffer](https://github.com/facebook/react-native/issues/21209) was not implemented.
129 | - Most of popular image manupulation libraries does not have support for react-native. eg : [jimp](https://www.npmjs.com/package/jimp), [jpeg-js](https://www.npmjs.com/package/jpeg-js) and [sharp](https://www.npmjs.com/package/sharp). We can use these libraries with some native node lib implemented in react native (some sort of polyfill).
130 | - For png this [library](https://github.com/photopea/UPNG.js) seems to be faster, but when tested this library with it, it is not retaining pixels at some places)
131 | - Use this [node-libs-react-native](https://www.npmjs.com/package/node-libs-react-native) if we need to use this library in react native (adds some mock or js implementation for fs, stream etc)
132 |
133 | ---
134 |
135 | Contributions of any kind welcome! :heart:
136 |
137 |
--------------------------------------------------------------------------------
/examples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "examples",
3 | "version": "1.0.0",
4 | "description": "Using in Nodejs env",
5 | "main": "index.js",
6 | "repository": "http://github.com/oolio-group/xml-escpos-helper.git",
7 | "license": "MIT",
8 | "private": false,
9 | "scripts": {
10 | "clean": "rm -rf ./dist && rm -rf ./tsconfig.build.tsbuildinfo",
11 | "compile": "yarn clean && tsc -p ./tsconfig.json",
12 | "print:basic": "yarn compile && yarn node ./dist/basic.js",
13 | "print:image": "yarn compile && yarn node ./dist/printImage.js",
14 | "print:table": "yarn compile && yarn node ./dist/printTable.js",
15 | "print:barcode": "yarn compile && yarn node ./dist/printBarcode.js"
16 | },
17 | "dependencies": {
18 | "@tillpos/xml-escpos-helper": "^0.1.8",
19 | "table": "^6.6.0"
20 | },
21 | "devDependencies": {
22 | "typescript": "^4.2.4"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/src/basic.ts:
--------------------------------------------------------------------------------
1 | import { sendDataToPrinter } from './network';
2 | import { TEMPLATES } from './templates';
3 |
4 | const printBasic = async () => {
5 | const input = {
6 | title: 'Sample',
7 | thankyouNote: 'Welcome...!'
8 | };
9 |
10 | await sendDataToPrinter(input, TEMPLATES.BASIC);
11 | };
12 |
13 | printBasic();
14 |
--------------------------------------------------------------------------------
/examples/src/network.ts:
--------------------------------------------------------------------------------
1 | import net from 'net';
2 | import { EscPos } from '@tillpos/xml-escpos-helper';
3 | const PRINTERS = [{ device_name: 'Epson', host: '192.168.0.8', port: 9100 }];
4 |
5 | const connectToPrinter = (
6 | host: string,
7 | port: number,
8 | buffer: Buffer,
9 | ): Promise => {
10 | return new Promise((res: (value: unknown) => void, rej) => {
11 | let device = new net.Socket();
12 |
13 | device.on('close', () => {
14 | if (device) {
15 | device.destroy();
16 | device = null;
17 | }
18 | res(true);
19 | return;
20 | });
21 |
22 | device.on('error', rej);
23 |
24 | device.connect(port, host, () => {
25 | device.write(buffer);
26 | device.emit('close');
27 | });
28 | });
29 | };
30 |
31 | export const sendDataToPrinter = async (input: any, template: string) => {
32 | const { host, port } = PRINTERS[0];
33 | const buffer = EscPos.getBufferFromTemplate(template, input);
34 | try {
35 | await connectToPrinter(host, port, (buffer as unknown) as Buffer);
36 | } catch (err) {
37 | console.log('some error', err);
38 | }
39 | };
40 |
--------------------------------------------------------------------------------
/examples/src/printBarCode.ts:
--------------------------------------------------------------------------------
1 | import { sendDataToPrinter } from './network';
2 | import { TEMPLATES } from './templates';
3 |
4 | const printBarCode = async () => {
5 | const input = {
6 | barcode: '12345678',
7 | };
8 |
9 | await sendDataToPrinter(input, TEMPLATES.BAR_CODE);
10 | };
11 |
12 | printBarCode();
13 |
--------------------------------------------------------------------------------
/examples/src/printImage.ts:
--------------------------------------------------------------------------------
1 | import { sendDataToPrinter } from './network';
2 | import { TEMPLATES } from './templates';
3 |
4 | const BASE64_PNG_IMAGE = `data:image/png;base64,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`;
5 |
6 | const printImage = async () => {
7 | const input = {
8 | title: 'Github',
9 | logo: BASE64_PNG_IMAGE
10 | };
11 |
12 | await sendDataToPrinter(input, TEMPLATES.PNG_IMAGE);
13 | };
14 |
15 | printImage();
16 |
--------------------------------------------------------------------------------
/examples/src/printTable.ts:
--------------------------------------------------------------------------------
1 | import { sendDataToPrinter } from './network';
2 | import { TEMPLATES } from './templates';
3 | import { getBorderCharacters, table } from 'table';
4 |
5 | const printTable = async () => {
6 | const versions = [
7 | ['React', '16.8'],
8 | ['Angular', '9'],
9 | ['Ember', '3.16'],
10 | ];
11 |
12 | const tableData = table(versions, {
13 | border: getBorderCharacters(`void`),
14 | drawHorizontalLine: () => {
15 | return false;
16 | },
17 | });
18 |
19 | await sendDataToPrinter({ tableData }, TEMPLATES.TABLE);
20 | };
21 |
22 | printTable();
23 |
--------------------------------------------------------------------------------
/examples/src/templates.ts:
--------------------------------------------------------------------------------
1 | export enum Templates {
2 | PNG_IMAGE = 'PNG_IMAGE',
3 | BASIC = 'BASIC',
4 | QR_CODE = 'QR_CODE',
5 | BAR_CODE = 'BAR_CODE',
6 | TABLE = 'TABLE',
7 | }
8 |
9 | export const TEMPLATES = {
10 | [Templates.BASIC]: `
11 |
12 |
13 |
14 | {{title}}
15 |
16 |
17 |
18 | {{#thankyouNote}}
19 |
20 | {{{thankyouNote}}}
21 |
22 | {{/thankyouNote}}
23 |
24 |
25 |
26 |
27 | `,
28 | [Templates.PNG_IMAGE]: `
29 |
30 |
31 |
32 |
33 | {{title}}
34 |
35 |
36 |
37 | {{logo}}
38 |
39 |
40 | `,
41 | [Templates.QR_CODE]: `
42 |
43 |
44 |
45 | {{qrcode}}
46 |
47 |
48 |
49 |
50 | `,
51 | [Templates.BAR_CODE]: `
52 |
53 |
54 |
55 |
56 | {{barcode}}
57 |
58 |
59 |
60 | `,
61 | [Templates.TABLE]: `
62 |
63 |
64 | {{tableData}}
65 |
66 | `,
67 | }
68 |
--------------------------------------------------------------------------------
/examples/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "esModuleInterop": true,
5 | "allowSyntheticDefaultImports": true,
6 | "target": "es6",
7 | "noImplicitAny": true,
8 | "moduleResolution": "node",
9 | "sourceMap": true,
10 | "outDir": "dist",
11 | "baseUrl": ".",
12 | "paths": {
13 | "*": [
14 | "node_modules/*",
15 | "src/types/*"
16 | ]
17 | }
18 | },
19 | "include": [
20 | "src/**/*"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/examples/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@tillpos/xml-escpos-helper@^0.1.8":
6 | version "0.1.8"
7 | resolved "https://registry.yarnpkg.com/@tillpos/xml-escpos-helper/-/xml-escpos-helper-0.1.8.tgz#d3a664d776fa022516f7c85b0280706892e7fa5b"
8 | integrity sha512-2VdutlzFUcCMYxoJ7LmdK4l6/lWXA3TInwoWOdZ2cQKB0V0T3qogrHQGxKgRrlhFds2co0kksaa4ePj5QlFLCw==
9 | dependencies:
10 | buffer "^6.0.3"
11 | mustache "^4.1.0"
12 | mutable-buffer "2.0.3"
13 | ndarray "^1.0.19"
14 | pngjs "^6.0.0"
15 | xml-parser "^1.2.1"
16 |
17 | ajv@^8.0.1:
18 | version "8.2.0"
19 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.2.0.tgz#c89d3380a784ce81b2085f48811c4c101df4c602"
20 | integrity sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==
21 | dependencies:
22 | fast-deep-equal "^3.1.1"
23 | json-schema-traverse "^1.0.0"
24 | require-from-string "^2.0.2"
25 | uri-js "^4.2.2"
26 |
27 | ansi-regex@^5.0.0:
28 | version "5.0.0"
29 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
30 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
31 |
32 | ansi-styles@^4.0.0:
33 | version "4.3.0"
34 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
35 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
36 | dependencies:
37 | color-convert "^2.0.1"
38 |
39 | astral-regex@^2.0.0:
40 | version "2.0.0"
41 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
42 | integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
43 |
44 | base64-js@^1.3.1:
45 | version "1.5.1"
46 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
47 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
48 |
49 | buffer@^6.0.3:
50 | version "6.0.3"
51 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
52 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
53 | dependencies:
54 | base64-js "^1.3.1"
55 | ieee754 "^1.2.1"
56 |
57 | color-convert@^2.0.1:
58 | version "2.0.1"
59 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
60 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
61 | dependencies:
62 | color-name "~1.1.4"
63 |
64 | color-name@~1.1.4:
65 | version "1.1.4"
66 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
67 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
68 |
69 | debug@^2.2.0:
70 | version "2.6.9"
71 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
72 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
73 | dependencies:
74 | ms "2.0.0"
75 |
76 | emoji-regex@^8.0.0:
77 | version "8.0.0"
78 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
79 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
80 |
81 | fast-deep-equal@^3.1.1:
82 | version "3.1.3"
83 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
84 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
85 |
86 | ieee754@^1.2.1:
87 | version "1.2.1"
88 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
89 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
90 |
91 | iota-array@^1.0.0:
92 | version "1.0.0"
93 | resolved "https://registry.yarnpkg.com/iota-array/-/iota-array-1.0.0.tgz#81ef57fe5d05814cd58c2483632a99c30a0e8087"
94 | integrity sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=
95 |
96 | is-buffer@^1.0.2:
97 | version "1.1.6"
98 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
99 | integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
100 |
101 | is-fullwidth-code-point@^3.0.0:
102 | version "3.0.0"
103 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
104 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
105 |
106 | json-schema-traverse@^1.0.0:
107 | version "1.0.0"
108 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
109 | integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
110 |
111 | lodash.clonedeep@^4.5.0:
112 | version "4.5.0"
113 | resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
114 | integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
115 |
116 | lodash.flatten@^4.4.0:
117 | version "4.4.0"
118 | resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
119 | integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
120 |
121 | lodash.truncate@^4.4.2:
122 | version "4.4.2"
123 | resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
124 | integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=
125 |
126 | ms@2.0.0:
127 | version "2.0.0"
128 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
129 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
130 |
131 | mustache@^4.1.0:
132 | version "4.2.0"
133 | resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
134 | integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
135 |
136 | mutable-buffer@2.0.3:
137 | version "2.0.3"
138 | resolved "https://registry.yarnpkg.com/mutable-buffer/-/mutable-buffer-2.0.3.tgz#67bca5568bf15d3f6035fb716e3899dc44901c8c"
139 | integrity sha1-Z7ylVovxXT9gNftxbjiZ3ESQHIw=
140 |
141 | ndarray@^1.0.19:
142 | version "1.0.19"
143 | resolved "https://registry.yarnpkg.com/ndarray/-/ndarray-1.0.19.tgz#6785b5f5dfa58b83e31ae5b2a058cfd1ab3f694e"
144 | integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==
145 | dependencies:
146 | iota-array "^1.0.0"
147 | is-buffer "^1.0.2"
148 |
149 | pngjs@^6.0.0:
150 | version "6.0.0"
151 | resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821"
152 | integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==
153 |
154 | punycode@^2.1.0:
155 | version "2.1.1"
156 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
157 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
158 |
159 | require-from-string@^2.0.2:
160 | version "2.0.2"
161 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
162 | integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
163 |
164 | slice-ansi@^4.0.0:
165 | version "4.0.0"
166 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
167 | integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==
168 | dependencies:
169 | ansi-styles "^4.0.0"
170 | astral-regex "^2.0.0"
171 | is-fullwidth-code-point "^3.0.0"
172 |
173 | string-width@^4.2.0:
174 | version "4.2.2"
175 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
176 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
177 | dependencies:
178 | emoji-regex "^8.0.0"
179 | is-fullwidth-code-point "^3.0.0"
180 | strip-ansi "^6.0.0"
181 |
182 | strip-ansi@^6.0.0:
183 | version "6.0.0"
184 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
185 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
186 | dependencies:
187 | ansi-regex "^5.0.0"
188 |
189 | table@^6.6.0:
190 | version "6.6.0"
191 | resolved "https://registry.yarnpkg.com/table/-/table-6.6.0.tgz#905654b79df98d9e9a973de1dd58682532c40e8e"
192 | integrity sha512-iZMtp5tUvcnAdtHpZTWLPF0M7AgiQsURR2DwmxnJwSy8I3+cY+ozzVvYha3BOLG2TB+L0CqjIz+91htuj6yCXg==
193 | dependencies:
194 | ajv "^8.0.1"
195 | lodash.clonedeep "^4.5.0"
196 | lodash.flatten "^4.4.0"
197 | lodash.truncate "^4.4.2"
198 | slice-ansi "^4.0.0"
199 | string-width "^4.2.0"
200 | strip-ansi "^6.0.0"
201 |
202 | typescript@^4.2.4:
203 | version "4.2.4"
204 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
205 | integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==
206 |
207 | uri-js@^4.2.2:
208 | version "4.4.1"
209 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
210 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
211 | dependencies:
212 | punycode "^2.1.0"
213 |
214 | xml-parser@^1.2.1:
215 | version "1.2.1"
216 | resolved "https://registry.yarnpkg.com/xml-parser/-/xml-parser-1.2.1.tgz#c31f4c34f2975db82ad013222120592736156fcd"
217 | integrity sha1-wx9MNPKXXbgq0BMiISBZJzYVb80=
218 | dependencies:
219 | debug "^2.2.0"
220 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tillpos/xml-escpos-helper",
3 | "description": "ESC/POS with XML interface",
4 | "keywords": [
5 | "escpos",
6 | "esc",
7 | "pos",
8 | "xml",
9 | "printer"
10 | ],
11 | "version": "0.3.1",
12 | "files": [
13 | "lib",
14 | "LICENSE",
15 | "README.md"
16 | ],
17 | "main": "lib/index",
18 | "types": "lib",
19 | "engines": {
20 | "node": ">=4.0.0"
21 | },
22 | "license": "Apache-2.0",
23 | "scripts": {
24 | "build": "yarn clean && yarn compile",
25 | "build:watch": "yarn compile -- -w",
26 | "clean": "rm -rf ./lib && rm -rf tsconfig.build.tsbuildinfo",
27 | "compile": "tsc -p ./tsconfig.build.json"
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "http://github.com/oolio-group/xml-escpos-helper.git"
32 | },
33 | "contributors": [
34 | "Snehit Velma "
35 | ],
36 | "bugs": {
37 | "url": "https://github.com/oolio-group/xml-escpos-helper/issues"
38 | },
39 | "dependencies": {
40 | "buffer": "^6.0.3",
41 | "mustache": "^4.1.0",
42 | "mutable-buffer": "2.0.3",
43 | "ndarray": "^1.0.19",
44 | "upng-js": "2.1.0",
45 | "xml-parser": "^1.2.1"
46 | },
47 | "devDependencies": {
48 | "@types/node": "^14.14.20",
49 | "@types/xml-parser": "^1.2.29",
50 | "ts-loader": "^2.3.4",
51 | "tslint": "^5.7.0",
52 | "tslint-eslint-rules": "^4.1.1",
53 | "typescript": "^4.1.3"
54 | }
55 | }
--------------------------------------------------------------------------------
/resources/ESCPOS_Command_Manual.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oolio-group/xml-escpos-helper/a80bd47b56ffe6400d9297c0bb0124300f46bd9a/resources/ESCPOS_Command_Manual.pdf
--------------------------------------------------------------------------------
/src/buffer-builder.ts:
--------------------------------------------------------------------------------
1 | import { Command } from "./command";
2 | import { MutableBuffer } from "mutable-buffer";
3 | import Image from "./image";
4 | export class BufferBuilder {
5 | private buffer: MutableBuffer;
6 | private hasGSCommand: boolean;
7 | private doEmphasise: boolean;
8 |
9 | constructor(private defaultSettings: boolean = true) {
10 | this.buffer = new MutableBuffer();
11 | this.hasGSCommand = true;
12 | this.doEmphasise = false;
13 |
14 | }
15 |
16 | public end(): BufferBuilder {
17 | return this;
18 | }
19 |
20 | public resetCharacterCodeTable(): BufferBuilder {
21 | this.buffer.write(Command.ESC_t(0));
22 | return this;
23 | }
24 |
25 | public setPrintColor(color: 'black' | 'red' = 'black'): BufferBuilder {
26 | this.buffer.write(Command.ESC_r(color === 'red' ? 1 : 0));
27 | return this;
28 | }
29 |
30 | public setCharacterSize(
31 | width: number = 0,
32 | height: number = 0
33 | ): BufferBuilder {
34 | if(this.hasGSCommand)
35 | {
36 | let size = (width << 4) + height;
37 | this.buffer.write(Command.GS_exclamation(size));
38 | }
39 | else{
40 | let mode = (width>0?(1<<5):0)+(height>0?(1<<4):0)+(this.doEmphasise?(1<<3):0)+1;
41 | this.buffer.write(Command.ESC_exclamation(mode));
42 | }
43 |
44 | return this;
45 | }
46 |
47 | public setPrintMode(setting:boolean): BufferBuilder {
48 | this.hasGSCommand = setting;
49 | if(setting) this.resetCharacterEncoding();
50 | this.resetCharacterSize();
51 | return this;
52 | }
53 |
54 | public resetCharacterSize(): BufferBuilder {
55 | if(this.hasGSCommand)
56 | {
57 | this.buffer.write(Command.GS_exclamation(0));
58 | }
59 | else
60 | {
61 | this.buffer.write(Command.ESC_exclamation(1));
62 | }
63 | return this;
64 | }
65 |
66 | public resetCharacterEncoding(): BufferBuilder {
67 | this.buffer.write(Command.FS_ob_C_fe_utf);
68 | return this;
69 | }
70 |
71 | public startCompressedCharacter(): BufferBuilder {
72 | this.buffer.write(Command.ESC_M(1));
73 | return this;
74 | }
75 |
76 | public endCompressedCharacter(): BufferBuilder {
77 | this.buffer.write(Command.ESC_M(0));
78 | return this;
79 | }
80 |
81 | public startBold(): BufferBuilder {
82 | this.hasGSCommand? this.buffer.write(Command.ESC_E(1)):this.doEmphasise=true;
83 | return this;
84 | }
85 |
86 | public endBold(): BufferBuilder {
87 | this.hasGSCommand? this.buffer.write(Command.ESC_E(0)):this.doEmphasise=false;
88 | return this;
89 | }
90 |
91 | public startUnderline(
92 | underlineMode: UNDERLINE_MODE = UNDERLINE_MODE.TWO_POINTS_OF_COARSE
93 | ): BufferBuilder {
94 | this.buffer.write(Command.ESC_minus(underlineMode));
95 | return this;
96 | }
97 |
98 | public endUnderline(): BufferBuilder {
99 | this.buffer.write(Command.ESC_minus(48));
100 | return this;
101 | }
102 |
103 | public startAlign(alignment: ALIGNMENT): BufferBuilder {
104 | this.buffer.write(Command.ESC_a(alignment));
105 | return this;
106 | }
107 |
108 | public resetAlign(): BufferBuilder {
109 | return this.startAlign(ALIGNMENT.LEFT);
110 | }
111 |
112 | public startWhiteMode(): BufferBuilder {
113 | this.buffer.write(Command.GS_B(1));
114 | return this;
115 | }
116 |
117 | public endWhiteMode(): BufferBuilder {
118 | this.buffer.write(Command.GS_B(0));
119 | return this;
120 | }
121 |
122 | public startReverseMode(): BufferBuilder {
123 | this.buffer.write(Command.ESC_rev(1));
124 | return this;
125 | }
126 |
127 | public endReverseMode(): BufferBuilder {
128 | this.buffer.write(Command.ESC_rev(0));
129 | return this;
130 | }
131 |
132 | public printBarcode(
133 | data: string,
134 | barcodeSystem: BARCODE_SYSTEM,
135 | width: BARCODE_WIDTH = BARCODE_WIDTH.DOT_375,
136 | height: number = 162,
137 | labelFont: BARCODE_LABEL_FONT = BARCODE_LABEL_FONT.FONT_A,
138 | labelPosition: BARCODE_LABEL_POSITION = BARCODE_LABEL_POSITION.BOTTOM,
139 | leftSpacing: number = 0
140 | ): BufferBuilder {
141 | this.buffer.write(Command.GS_w(width)); // width
142 | this.buffer.write(Command.GS_h(height)); // height
143 | this.buffer.write(Command.GS_x(leftSpacing)); // left spacing
144 | this.buffer.write(Command.GS_f(labelFont)); // HRI font
145 | this.buffer.write(Command.GS_H(labelPosition)); // HRI font
146 | this.buffer.write(Command.GS_K(barcodeSystem, data.length)); // data is a string in UTF-8
147 | this.buffer.write(data, "ascii");
148 | return this;
149 | }
150 |
151 | public printQRcode(data: string, model: number, size: number, ecLevel: number): BufferBuilder {
152 | let x = data.length + 3;
153 | let pL = Math.floor(x % 256);
154 | let pH = Math.floor(x / 256);
155 |
156 | this.buffer.write(Command.QR_MODEL(model));
157 | this.buffer.write(Command.QR_SIZE(size));
158 | this.buffer.write(Command.EC_LEVEL(ecLevel));
159 | this.buffer.write(Command.STORE_QR(pL, pH));
160 | this.buffer.write(data, "ascii");
161 | this.buffer.write(Command.PRINT_QR());
162 |
163 | return this;
164 | }
165 |
166 | public printBitmap(
167 | image: number[],
168 | width: number,
169 | height: number,
170 | scale: BITMAP_SCALE = BITMAP_SCALE.NORMAL
171 | ): BufferBuilder {
172 | //TODO
173 | return this;
174 | }
175 |
176 | public printText(text: string): BufferBuilder {
177 | this.buffer.write(text, "utf8");
178 | return this;
179 | }
180 |
181 | public printTextLine(text: string): BufferBuilder {
182 | return this.printText(text).breakLine();
183 | }
184 |
185 | public breakLine(lines: number = 0): BufferBuilder {
186 | this.buffer.write(Command.ESC_d(lines));
187 | return this;
188 | }
189 |
190 | public lineFeed(): BufferBuilder {
191 | this.buffer.write(Command.LF);
192 | return this;
193 | }
194 |
195 | public transmitStatus(statusType: STATUS_TYPE): BufferBuilder {
196 | this.buffer.write(Command.DLE_EOT(statusType));
197 | return this;
198 | }
199 |
200 | public build(): number[] {
201 | if (this.defaultSettings) {
202 | this.lineFeed();
203 | this.buffer.write(Command.ESC_init);
204 | }
205 |
206 | return this.buffer.flush();
207 | }
208 |
209 | /**
210 | * Register Paper Cut Action
211 | * @return BufferBuilder
212 | */
213 | public paperCut(): BufferBuilder {
214 | this.buffer.write(Command.GS_v(66,50));
215 | return this;
216 | }
217 |
218 | /**
219 | * Register open cash drawer action
220 | * @return BufferBuilder
221 | */
222 | public openCashDrawer(): BufferBuilder {
223 | // kick drawer 1, pin 2
224 | this.buffer.write(Command.CD_KICK_1());
225 | // kick drawer 2, pin 5
226 | this.buffer.write(Command.CD_KICK_2());
227 | return this;
228 | }
229 |
230 | public printImage(image: Image, mode: RASTER_MODE): BufferBuilder {
231 | if (!(image instanceof Image)) {
232 | throw new TypeError("not supported");
233 | }
234 | const raster = image.toRaster();
235 | this.buffer.write(Command.GS_v0(mode));
236 | this.buffer.writeUInt16LE(raster.width);
237 | this.buffer.writeUInt16LE(raster.height);
238 | this.buffer.write(raster.data);
239 | return this;
240 | }
241 | }
242 |
243 | export enum UNDERLINE_MODE {
244 | ONE_POINT_OF_COARSE = 49,
245 | TWO_POINTS_OF_COARSE = 50,
246 | }
247 |
248 | export enum ALIGNMENT {
249 | LEFT = 48,
250 | CENTER = 49,
251 | RIGHT = 50,
252 | }
253 |
254 | export enum BARCODE_SYSTEM {
255 | UPC_A = 65,
256 | UPC_E = 66,
257 | EAN_13 = 67,
258 | EAN_8 = 68,
259 | CODE_39 = 69,
260 | ITF = 70,
261 | CODABAR = 71,
262 | CODE_93 = 72,
263 | CODE_128 = 73,
264 | }
265 |
266 | export enum BARCODE_WIDTH {
267 | DOT_250 = 2,
268 | DOT_375 = 3,
269 | DOT_560 = 4,
270 | DOT_625 = 5,
271 | DOT_750 = 6,
272 | }
273 |
274 | export enum BARCODE_LABEL_FONT {
275 | FONT_A = 48,
276 | FONT_B = 49,
277 | }
278 |
279 | export enum BARCODE_LABEL_POSITION {
280 | NOT_PRINT = 48,
281 | ABOVE = 49,
282 | BOTTOM = 50,
283 | ABOVE_BOTTOM = 51,
284 | }
285 |
286 | export enum QR_EC_LEVEL {
287 | L = 0,
288 | M = 1,
289 | Q = 2,
290 | H = 3,
291 | }
292 |
293 | export enum BITMAP_SCALE {
294 | NORMAL = 48,
295 | DOUBLE_WIDTH = 49,
296 | DOUBLE_HEIGHT = 50,
297 | FOUR_TIMES = 51,
298 | }
299 |
300 | export enum STATUS_TYPE {
301 | PRINTER_STATUS = 1,
302 | OFFLINE_STATUS = 2,
303 | ERROR_STATUS = 3,
304 | PAPER_ROLL_SENSOR_STATUS = 4,
305 | }
306 |
307 | export enum RASTER_MODE {
308 | NORMAL = 0,
309 | DOUBLE_WIDTH = 1,
310 | DOUBLE_HEIGHT = 2,
311 | DOUBLE_WIDTH_HEIGHT = 3,
312 | }
313 |
--------------------------------------------------------------------------------
/src/command.ts:
--------------------------------------------------------------------------------
1 | export class Command {
2 |
3 | public static ESC: number = 0x1B;
4 | public static FF: number = 0x0C;
5 | public static FS: number = 0x1C;
6 | public static GS: number = 0x1D;
7 | public static DC1: number = 0x11;
8 | public static DC4: number = 0x14;
9 | public static DLE: number = 0x10;
10 | public static NL: number = 0x0A;
11 | public static SP: number = 0x20;
12 | public static US: number = 0x1F;
13 |
14 | public static DLE_EOT = (n: number): number[] => [Command.DLE, 0x04, n]; // DLEEOTn
15 |
16 | public static ESC_init: number[] = [Command.ESC, 0x40]; //ESC@
17 | public static ESC_exclamation = (n: number): number[] => [Command.ESC, 0x21, n]; // ESC!n
18 | public static ESC_minus = (n: number): number[] => [Command.ESC, 0x2D, n]; // ESC-n
19 | public static ESC_rev = (n: number): number[] => [Command.ESC, 0x7B, n]; // ESC{n
20 | public static ESC_a = (n: number): number[] => [Command.ESC, 0x61, n]; // ESCan
21 | public static ESC_d = (n: number): number[] => [Command.ESC, 0x64, n]; // ESCdn
22 | public static ESC_E = (n: number): number[] => [Command.ESC, 0x45, n]; // ESCEn
23 | public static ESC_G = (n: number): number[] => [Command.ESC, 0x47, n]; // ESCGn
24 | public static ESC_J = (n: number): number[] => [Command.ESC, 0x4A, n]; // ESCJn
25 | public static ESC_M = (n: number): number[] => [Command.ESC, 0x4D, n]; // ESCMn
26 | public static ESC_t = (n: number): number[] => [Command.ESC, 0x07, n]; // ESCtn
27 | public static ESC_Z = (m: number, n: number, k: number): number[] => [Command.ESC, 0x5A, m, n, k]; // ESCZmnk
28 | public static ESC_r = (n: number): number[] => [Command.ESC, 0x72, n]; // ESCR
29 |
30 |
31 | public static FS_and: number[] = [Command.FS, 0x40]; //ESC@
32 | public static FS_ob_C_fe_utf = [Command.FS, 0x28, 0x43, 0x02, 0x00, 0x30, 0x02]; //UTF-8 encoding
33 |
34 | public static GS_exclamation = (n: number): number[] => [Command.GS, 0x21, n]; // ESC!n
35 | public static GS_B = (n: number): number[] => [Command.GS, 0x42, n]; // GSBn
36 | public static GS_f = (n: number): number[] => [Command.GS, 0x66, n]; // GSfn
37 | public static GS_h = (n: number): number[] => [Command.GS, 0x68, n]; // GShn
38 | public static GS_H = (n: number): number[] => [Command.GS, 0x48, n]; // GSHn
39 | public static GS_K = (m: number, n: number): number[] => [Command.GS, 0x6B, m, n]; // GSKmn
40 | public static GS_v0 = (m: number): number[] => [Command.GS, 0x76, 0x30, m]; // GSv0m
41 | public static GS_w = (n: number): number[] => [Command.GS, 0x77, n]; // GSwn
42 | public static GS_x = (n: number): number[] => [Command.GS, 0x78, n]; // GSxn
43 | public static GS_v = (m: number, n: number): number[] => [Command.GS, 0x56, m, n]; // GSv
44 | public static ESC_ak = (n: number): number[] => [Command.ESC, 0x2A, n]; // ESC*n
45 | public static ESC_akp = (m: number, nL: number,nH: number ): number[] => [Command.ESC, 0x2A, m, nL, nH]; // ESC*n
46 |
47 | public static LF: number[] = [Command.NL];
48 |
49 |
50 | // Cash Drawer
51 | public static CD_KICK_1 = (): number[] => [Command.ESC, 0x70, 0x00]; // Sends a pulse to pin 2
52 | public static CD_KICK_2 = (): number[] => [Command.ESC, 0x70, 0x01]; // Sends a pulse to pin 5
53 |
54 | //QR Code
55 | public static QR_MODEL =(n: number): number[]=> [29, 40, 107, 4, 0, 49, 65, n, 0]; //Select QR model, n = 49/50
56 | //[29 40 107 4 0 49 65 n1 n2]
57 | public static QR_SIZE =(n: number): number[] => [29, 40, 107, 3, 0, 49, 67, n]; //Set QR size, n = 8?
58 | //[29 40 107 3 0 49 67 n]
59 | public static EC_LEVEL =(n: number): number[] => [29, 40, 107, 3, 0, 49, 69, n]; //Set error correction level for QR, n = 48/49/50/51
60 | //[29 40 107 3 0 49 69 n]
61 | public static STORE_QR =(pL, pH): number[] => [29, 40, 107, pL, pH, 49, 80, 48]; //Store QR data in symbol storage area
62 | //[29 40 107 pL pH 49 80 48 d1…dk]
63 | public static PRINT_QR =(): number[] => [29, 40, 107, 3, 0, 49, 81, 48]; //Print QR from data in symbol storage area
64 | //[29 40 107 3 0 49 81 m]
65 | }
66 |
--------------------------------------------------------------------------------
/src/escpos.ts:
--------------------------------------------------------------------------------
1 | import { TemplateParser } from './template-parser';
2 | import { XMLParser } from './xml-parser';
3 | import { BufferBuilder } from './buffer-builder';
4 |
5 | export class EscPos {
6 |
7 | public static getBufferFromTemplate(template: string, data: any): number[] {
8 | let templateParser = new TemplateParser();
9 | return templateParser.parser(template, data).build();
10 | }
11 |
12 | public static getBufferFromXML(xml: string): number[] {
13 | let xmlParser = new XMLParser();
14 | return xmlParser.parser(xml).build();
15 | }
16 |
17 | public static getBufferBuilder(): BufferBuilder {
18 | return new BufferBuilder();
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/image.ts:
--------------------------------------------------------------------------------
1 | class Image {
2 | public pixels;
3 | public data;
4 | constructor(pixels) {
5 | this.pixels = pixels;
6 |
7 | this.data = [];
8 | function rgb(pixel) {
9 | return {
10 | r: pixel[0],
11 | g: pixel[1],
12 | b: pixel[2],
13 | a: pixel[3],
14 | };
15 | }
16 |
17 | var self = this;
18 | for (var i = 0; i < this.pixels.data.length; i += this.size.colors) {
19 | this.data.push(
20 | rgb(
21 | new Array(this.size.colors).fill(0).map(function (_, b) {
22 | return self.pixels.data[i + b];
23 | })
24 | )
25 | );
26 | }
27 |
28 | this.data = this.data.map(function (pixel) {
29 | if (pixel.a == 0) return 0;
30 | var shouldBeWhite = pixel.r > 200 && pixel.g > 200 && pixel.b > 200;
31 | return shouldBeWhite ? 0 : 1;
32 | });
33 | }
34 |
35 | /**
36 | * [description]
37 | * @return {[type]} [description]
38 | */
39 | get size() {
40 | return {
41 | width: this.pixels.shape[0],
42 | height: this.pixels.shape[1],
43 | colors: this.pixels.shape[2],
44 | };
45 | }
46 |
47 | /**
48 | * [toBitmap description]
49 | * @param {[type]} density [description]
50 | * @return {[type]} [description]
51 | */
52 | public toBitmap(density) {
53 | density = density || 24;
54 |
55 | var ld,
56 | result = [];
57 | var x, y, b, l, i;
58 | var c = density / 8;
59 |
60 | // n blocks of lines
61 | var n = Math.ceil(this.size.height / density);
62 |
63 | for (y = 0; y < n; y++) {
64 | // line data
65 | ld = result[y] = [];
66 |
67 | for (x = 0; x < this.size.width; x++) {
68 | for (b = 0; b < density; b++) {
69 | i = x * c + (b >> 3);
70 |
71 | if (ld[i] === undefined) {
72 | ld[i] = 0;
73 | }
74 |
75 | l = y * density + b;
76 | if (l < this.size.height) {
77 | if (this.data[l * this.size.width + x]) {
78 | ld[i] += 0x80 >> (b & 0x7);
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
85 | return {
86 | data: result,
87 | density: density,
88 | };
89 | }
90 |
91 | /**
92 | * [toRaster description]
93 | * @return {[type]} [description]
94 | */
95 | public toRaster() {
96 | var result = [];
97 | var width = this.size.width;
98 | var height = this.size.height;
99 | var data = this.data;
100 |
101 | // n blocks of lines
102 | var n = Math.ceil(width / 8);
103 | var x, y, b, c, i;
104 |
105 | for (y = 0; y < height; y++) {
106 | for (x = 0; x < n; x++) {
107 | for (b = 0; b < 8; b++) {
108 | i = x * 8 + b;
109 |
110 | if (result[y * n + x] === undefined) {
111 | result[y * n + x] = 0;
112 | }
113 |
114 | c = x * 8 + b;
115 | if (c < width) {
116 | if (data[y * width + i]) {
117 | result[y * n + x] += 0x80 >> (b & 0x7);
118 | }
119 | }
120 | }
121 | }
122 | }
123 | return {
124 | data: result,
125 | width: n,
126 | height: height,
127 | };
128 | }
129 | }
130 |
131 | export default Image;
132 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | global.Buffer = global.Buffer || require('buffer').Buffer;
2 | export * from './template-parser';
3 | export * from './xml-parser';
4 | export * from './buffer-builder';
5 | export * from './escpos';
6 |
--------------------------------------------------------------------------------
/src/node-factory.ts:
--------------------------------------------------------------------------------
1 | import AlignNode from './nodes/align-node';
2 | import BarcodeNode from './nodes/barcode-node';
3 | import BoldNode from './nodes/bold-node';
4 | import BreakLineNode from './nodes/break-line-node';
5 | import DocumentNode from './nodes/document-node';
6 | import LineFeedNode from './nodes/line-feed-node';
7 | import QRcodeNode from './nodes/qrcode-node';
8 | import SmallNode from './nodes/small-node';
9 | import TextNode from './nodes/text-node';
10 | import TextLineNode from './nodes/text-line-node';
11 | import UnderlineNode from './nodes/underline-node';
12 | import WhiteModeNode from './nodes/white-mode-node';
13 | import PaperCutNode from './nodes/paper-cut-node';
14 | import ImageNode from './nodes/image-node';
15 | import OpenCashDrawerNode from './nodes/open-cash-drawer-node';
16 | import PrintModeNode from './nodes/print-mode';
17 |
18 | export class NodeFactory {
19 |
20 | public static create(nodeType: String, node) {
21 | switch (nodeType) {
22 | case 'align': return new AlignNode(node);
23 | case 'barcode': return new BarcodeNode(node);
24 | case 'bold': return new BoldNode(node);
25 | case 'break-line': return new BreakLineNode(node);
26 | case 'document': return new DocumentNode(node);
27 | case 'line-feed': return new LineFeedNode(node);
28 | case 'qrcode': return new QRcodeNode(node);
29 | case 'small': return new SmallNode(node);
30 | case 'text': return new TextNode(node);
31 | case 'text-line': return new TextLineNode(node);
32 | case 'underline': return new UnderlineNode(node);
33 | case 'white-mode': return new WhiteModeNode(node);
34 | case 'paper-cut': return new PaperCutNode(node);
35 | case 'open-cash-drawer': return new OpenCashDrawerNode(node);
36 | case 'image': return new ImageNode(node);
37 | case 'print-mode': return new PrintModeNode(node);
38 |
39 | default: return null;
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/nodes/align-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder, ALIGNMENT } from '../buffer-builder';
3 |
4 | export default class AlignNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | switch (this.attributes.mode) {
12 | case 'center':
13 | bufferBuilder.startAlign(ALIGNMENT.CENTER); break;
14 | case 'left':
15 | bufferBuilder.startAlign(ALIGNMENT.LEFT); break;
16 | case 'right':
17 | bufferBuilder.startAlign(ALIGNMENT.RIGHT); break;
18 | }
19 | return bufferBuilder;
20 | }
21 |
22 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
23 | bufferBuilder.resetAlign();
24 | return bufferBuilder;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/nodes/barcode-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder, BARCODE_SYSTEM, BARCODE_WIDTH, BARCODE_LABEL_FONT, BARCODE_LABEL_POSITION } from '../buffer-builder';
3 |
4 | export default class BarcodeNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | let system, width, height, labelFont, labelPosition, leftSpacing;
12 |
13 | switch (this.attributes.system) {
14 | case 'UPC_A':
15 | system = BARCODE_SYSTEM.UPC_A; break;
16 | case 'UPC_E':
17 | system = BARCODE_SYSTEM.UPC_E; break;
18 | case 'EAN_13':
19 | system = BARCODE_SYSTEM.EAN_13; break;
20 | case 'EAN_8':
21 | system = BARCODE_SYSTEM.EAN_8; break;
22 | case 'CODE_39':
23 | system = BARCODE_SYSTEM.CODE_39; break;
24 | case 'ITF':
25 | system = BARCODE_SYSTEM.ITF; break;
26 | case 'CODABAR':
27 | system = BARCODE_SYSTEM.CODABAR; break;
28 | case 'CODE_93':
29 | system = BARCODE_SYSTEM.CODE_93; break;
30 | case 'CODE_128':
31 | system = BARCODE_SYSTEM.CODE_128; break;
32 | }
33 |
34 | switch (this.attributes.width) {
35 | case 'DOT_250':
36 | width = BARCODE_WIDTH.DOT_250; break;
37 | case 'DOT_375':
38 | width = BARCODE_WIDTH.DOT_375; break;
39 | case 'DOT_560':
40 | width = BARCODE_WIDTH.DOT_560; break;
41 | case 'DOT_625':
42 | width = BARCODE_WIDTH.DOT_625; break;
43 | case 'DOT_750':
44 | width = BARCODE_WIDTH.DOT_750; break;
45 | default:
46 | width = BARCODE_WIDTH.DOT_375;
47 | }
48 |
49 | switch (this.attributes.labelFont) {
50 | case 'FONT_A':
51 | labelFont = BARCODE_LABEL_FONT.FONT_A; break;
52 | case 'FONT_B':
53 | labelFont = BARCODE_LABEL_FONT.FONT_B; break;
54 | default:
55 | labelFont = BARCODE_LABEL_FONT.FONT_A;
56 | }
57 |
58 | switch (this.attributes.labelPosition) {
59 | case 'NOT_PRINT':
60 | labelPosition = BARCODE_LABEL_POSITION.NOT_PRINT; break;
61 | case 'ABOVE':
62 | labelPosition = BARCODE_LABEL_POSITION.ABOVE; break;
63 | case 'BOTTOM':
64 | labelPosition = BARCODE_LABEL_POSITION.BOTTOM; break;
65 | case 'ABOVE_BOTTOM':
66 | labelPosition = BARCODE_LABEL_POSITION.ABOVE_BOTTOM; break;
67 | default:
68 | labelPosition = BARCODE_LABEL_POSITION.BOTTOM;
69 | }
70 |
71 | if (/\d+/.test(this.attributes.height)) {
72 | height = parseInt(this.attributes.height);
73 | } else {
74 | height = 162;
75 | }
76 |
77 | if (/\d+/.test(this.attributes.leftSpacing)) {
78 | leftSpacing = parseInt(this.attributes.leftSpacing);
79 | } else {
80 | leftSpacing = 0;
81 | }
82 |
83 | if (system && this.content) {
84 | bufferBuilder.printBarcode(this.content, system, width, height, labelFont, labelPosition, leftSpacing);
85 | }
86 |
87 | return bufferBuilder;
88 | }
89 |
90 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
91 | return bufferBuilder;
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/src/nodes/bold-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class BoldNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | bufferBuilder.startBold();
12 | return bufferBuilder;
13 | }
14 |
15 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
16 | bufferBuilder.endBold();
17 | return bufferBuilder;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/nodes/break-line-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class BreakLineNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | let lines: number = 0;
12 | if (/\d+/.test(this.attributes.lines))
13 | lines = parseInt(this.attributes.lines) - 1;
14 |
15 | return bufferBuilder.breakLine(lines);
16 | }
17 |
18 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
19 | return bufferBuilder;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/nodes/document-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class DocumentNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | if (this.attributes.reverse)
12 | bufferBuilder.startReverseMode();
13 |
14 | return bufferBuilder;
15 | }
16 |
17 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
18 | bufferBuilder.endReverseMode();
19 | return bufferBuilder;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/nodes/image-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder, RASTER_MODE } from '../buffer-builder';
3 | import ndarray from 'ndarray';
4 | import Image from '../image';
5 | import upngjs from 'upng-js';
6 |
7 | export default class ImageNode extends XMLNode {
8 | constructor(node: any) {
9 | super(node);
10 | }
11 |
12 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
13 | const img_data = upngjs.decode(
14 | Buffer.from(this.content.replace(///g, '/'), 'base64'),
15 | );
16 |
17 | const pixels = ndarray(
18 | new Uint8Array(img_data.data),
19 | [img_data.width | 0, img_data.height | 0, 4],
20 | [4, (4 * img_data.width) | 0, 1],
21 | 0,
22 | );
23 |
24 | let mode;
25 | switch (this.attributes.mode) {
26 | case 'NORMAL':
27 | mode = RASTER_MODE.NORMAL;
28 | break;
29 | case 'DW':
30 | mode = RASTER_MODE.DOUBLE_WIDTH;
31 | break;
32 | case 'DH':
33 | mode = RASTER_MODE.DOUBLE_HEIGHT;
34 | break;
35 | case 'DWH':
36 | mode = RASTER_MODE.DOUBLE_WIDTH_HEIGHT;
37 | break;
38 | default:
39 | mode = RASTER_MODE.NORMAL;
40 | }
41 |
42 | bufferBuilder.printImage(new Image(pixels), mode);
43 | return bufferBuilder;
44 | }
45 |
46 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
47 | return bufferBuilder;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/nodes/line-feed-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class LineFeedNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | return bufferBuilder.lineFeed();
12 | }
13 |
14 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
15 | return bufferBuilder;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/nodes/open-cash-drawer-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class OpenCashDrawerNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | return bufferBuilder.openCashDrawer();
12 | }
13 |
14 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
15 | return bufferBuilder;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/src/nodes/paper-cut-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class PaperCutNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | return bufferBuilder.paperCut();
12 | }
13 |
14 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
15 | return bufferBuilder;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/src/nodes/print-mode.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class PrintModeNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | if(this.attributes.mode === 'U220')
12 | {
13 | bufferBuilder.setPrintMode(false);
14 | }
15 | else
16 | {
17 | bufferBuilder.setPrintMode(true);
18 | }
19 | return bufferBuilder;
20 | }
21 |
22 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
23 | bufferBuilder.resetAlign();
24 | return bufferBuilder;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/nodes/qrcode-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder, QR_EC_LEVEL } from '../buffer-builder';
3 |
4 | export default class QRcodeNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | let qrModel, qrSize, ecLevel;
12 |
13 | switch (this.attributes.model) {
14 | case '1':
15 | qrModel = 49; break;
16 | case '2':
17 | qrModel = 50; break;
18 | default:
19 | qrModel = 50;
20 | }
21 |
22 | if (/\d+/.test(this.attributes.size)) {
23 | qrSize = parseInt(this.attributes.size);
24 | }
25 | else {
26 | qrSize = 8;
27 | }
28 |
29 | switch (this.attributes.ecl) {
30 | case 'L':
31 | ecLevel = 48; break;
32 | case 'M':
33 | ecLevel = 49; break;
34 | case 'Q':
35 | ecLevel = 50; break;
36 | case 'H':
37 | ecLevel = 51; break;
38 | default:
39 | ecLevel = 48;
40 | }
41 |
42 | if (this.content) {
43 | let url = this.content.replace(/ /g, ' ').replace(/&/g, '&').replace(/=/g, '=').replace(///g, '/').replace(/</g, '<').replace(/>/g, '>').replace(/'/g, "'").replace(/"/g, '"')
44 | bufferBuilder.printQRcode(url, qrModel, qrSize, ecLevel);
45 | }
46 |
47 | return bufferBuilder;
48 | }
49 |
50 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
51 | return bufferBuilder;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/nodes/small-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class SmallNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | bufferBuilder.startCompressedCharacter();
12 | return bufferBuilder;
13 | }
14 |
15 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
16 | bufferBuilder.endCompressedCharacter();
17 | return bufferBuilder;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/nodes/text-line-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 | import TextNode from './text-node';
4 |
5 | export default class TextLineNode extends XMLNode {
6 |
7 | private textNode: TextNode;
8 |
9 | constructor(node: any) {
10 | super(node);
11 | this.textNode = new TextNode(node);
12 | }
13 |
14 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
15 | return this.textNode.open(bufferBuilder);
16 | }
17 |
18 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
19 | return this.textNode.close(bufferBuilder).breakLine();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/nodes/text-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class TextNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 |
12 | if (/\d+:\d+/.test(this.attributes.size)) {
13 | let size: number[] = new String(this.attributes.size).split(':').map(entry => parseInt(entry));
14 | bufferBuilder.setCharacterSize(size[0], size[1]);
15 | }
16 |
17 | bufferBuilder.setPrintColor(this.attributes.color);
18 |
19 | let text = this.getContent().replace(/ /g, ' ').replace(/<tab>/g, ' ').replace(/&/g, '&').replace(/=/g, '=').replace(///g, '/').replace(/</g, '<').replace(/>/g, '>').replace(/'/g, "'").replace(/"/g, '"');
20 |
21 | bufferBuilder.printText(text);
22 | return bufferBuilder;
23 | }
24 |
25 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
26 | bufferBuilder.resetCharacterSize();
27 | return bufferBuilder;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/nodes/underline-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder, UNDERLINE_MODE } from '../buffer-builder';
3 |
4 | export default class UnderlineNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | switch (this.attributes.mode) {
12 | case 'one-point':
13 | bufferBuilder.startUnderline(UNDERLINE_MODE.ONE_POINT_OF_COARSE); break;
14 | case 'two-points':
15 | bufferBuilder.startUnderline(UNDERLINE_MODE.TWO_POINTS_OF_COARSE); break;
16 | default:
17 | bufferBuilder.startUnderline();
18 | }
19 | return bufferBuilder;
20 | }
21 |
22 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
23 | bufferBuilder.endUnderline();
24 | return bufferBuilder;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/nodes/white-mode-node.ts:
--------------------------------------------------------------------------------
1 | import { XMLNode } from '../xml-node';
2 | import { BufferBuilder } from '../buffer-builder';
3 |
4 | export default class WhiteModeNode extends XMLNode {
5 |
6 | constructor(node: any) {
7 | super(node);
8 | }
9 |
10 | public open(bufferBuilder: BufferBuilder): BufferBuilder {
11 | bufferBuilder.startWhiteMode();
12 | return bufferBuilder;
13 | }
14 |
15 | public close(bufferBuilder: BufferBuilder): BufferBuilder {
16 | bufferBuilder.endWhiteMode();
17 | return bufferBuilder;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/template-parser.ts:
--------------------------------------------------------------------------------
1 | import Mustache from 'mustache';
2 | import { XMLParser } from './xml-parser';
3 | import { BufferBuilder } from './buffer-builder';
4 |
5 | export class TemplateParser {
6 | private mustache: any;
7 |
8 | constructor() {
9 | this.mustache = Mustache;
10 | }
11 |
12 | public parser(template, scope): BufferBuilder {
13 | const xml = this.mustache.render(template, scope);
14 | return new XMLParser().parser(xml);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/xml-node.ts:
--------------------------------------------------------------------------------
1 | import { BufferBuilder } from './buffer-builder';
2 |
3 | export abstract class XMLNode {
4 |
5 | protected attributes: any;
6 | protected content: string;
7 | protected children: XMLNode[];
8 |
9 | constructor(node: any) {
10 | this.attributes = node.attributes || {};
11 | this.content = node.content;
12 | this.children = [];
13 | }
14 |
15 | public addChild(child: XMLNode) {
16 | if (child)
17 | this.children.push(child);
18 | }
19 |
20 | protected getContent(): string {
21 | return this.content;
22 | }
23 |
24 | public abstract open(bufferBuilder: BufferBuilder): BufferBuilder | Promise;
25 |
26 | public abstract close(bufferBuilder: BufferBuilder): BufferBuilder;
27 |
28 | public draw(bufferBuilder: BufferBuilder): BufferBuilder {
29 |
30 | // open tag
31 | this.open(bufferBuilder);
32 |
33 | if (this.children.length > 0) {
34 | this.children.forEach(child => child.draw(bufferBuilder));
35 | }
36 |
37 | // close tag
38 | this.close(bufferBuilder);
39 |
40 | return bufferBuilder;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/xml-parser.ts:
--------------------------------------------------------------------------------
1 | import parser from 'xml-parser';
2 | import { BufferBuilder } from './buffer-builder';
3 | import { XMLNode } from './xml-node';
4 | import { NodeFactory } from './node-factory';
5 |
6 | export class XMLParser {
7 |
8 | public parser(xml: string): BufferBuilder {
9 | let parsedXML = parser(xml);
10 | return this.compile(parsedXML);
11 | }
12 |
13 | private compile(parsedXML: any): BufferBuilder {
14 | let bufferBuilder = new BufferBuilder();
15 | let rootNode = this.adapter(parsedXML.root, null);
16 | return rootNode.draw(bufferBuilder);
17 | }
18 |
19 | private adapter(node: any, parentNode): XMLNode {
20 | let xmlNode: XMLNode = NodeFactory.create(node.name, node);
21 | if (parentNode) parentNode.addChild(xmlNode);
22 | if (node.children.length > 0) {
23 | node.children.forEach(child => {
24 | this.adapter(child, xmlNode);
25 | });
26 | }
27 | return xmlNode;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "ES2019",
5 | "outDir": "lib",
6 | "declaration": true,
7 | "esModuleInterop": true,
8 | "moduleResolution": "node",
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "resolveJsonModule": true,
12 | "skipLibCheck": true
13 | },
14 |
15 | "exclude": ["node_modules", "dist", "examples"]
16 | }
17 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.build.json",
3 |
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "esModuleInterop": true,
7 | "resolveJsonModule": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-duplicate-variable": true,
4 | "no-unused-variable": [
5 | true
6 | ]
7 | },
8 | "rulesDirectory": [
9 | "node_modules/tslint-eslint-rules/dist/rules"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@^7.0.0":
6 | version "7.12.11"
7 | resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz"
8 | integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
9 | dependencies:
10 | "@babel/highlight" "^7.10.4"
11 |
12 | "@babel/helper-validator-identifier@^7.10.4":
13 | version "7.12.11"
14 | resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz"
15 | integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
16 |
17 | "@babel/highlight@^7.10.4":
18 | version "7.10.4"
19 | resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz"
20 | integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
21 | dependencies:
22 | "@babel/helper-validator-identifier" "^7.10.4"
23 | chalk "^2.0.0"
24 | js-tokens "^4.0.0"
25 |
26 | "@types/node@^14.14.20":
27 | version "14.14.20"
28 | resolved "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz"
29 | integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==
30 |
31 | "@types/xml-parser@^1.2.29":
32 | version "1.2.29"
33 | resolved "https://registry.npmjs.org/@types/xml-parser/-/xml-parser-1.2.29.tgz"
34 | integrity sha512-l5ID65aPDctN/dZYkDgLOEBuoHrD8S9TyfD5soORUtVHKyOs7Wr66iNxAtcmT/tER1GeYqp51jR6l08gmsRcZg==
35 |
36 | ansi-styles@^3.2.1:
37 | version "3.2.1"
38 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
39 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
40 | dependencies:
41 | color-convert "^1.9.0"
42 |
43 | argparse@^1.0.7:
44 | version "1.0.10"
45 | resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
46 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
47 | dependencies:
48 | sprintf-js "~1.0.2"
49 |
50 | balanced-match@^1.0.0:
51 | version "1.0.0"
52 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
53 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
54 |
55 | base64-js@^1.3.1:
56 | version "1.5.1"
57 | resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
58 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
59 |
60 | big.js@^5.2.2:
61 | version "5.2.2"
62 | resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz"
63 | integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
64 |
65 | brace-expansion@^1.1.7:
66 | version "1.1.11"
67 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
68 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
69 | dependencies:
70 | balanced-match "^1.0.0"
71 | concat-map "0.0.1"
72 |
73 | buffer@^6.0.3:
74 | version "6.0.3"
75 | resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz"
76 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
77 | dependencies:
78 | base64-js "^1.3.1"
79 | ieee754 "^1.2.1"
80 |
81 | builtin-modules@^1.1.1:
82 | version "1.1.1"
83 | resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz"
84 | integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
85 |
86 | chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0:
87 | version "2.4.2"
88 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
89 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
90 | dependencies:
91 | ansi-styles "^3.2.1"
92 | escape-string-regexp "^1.0.5"
93 | supports-color "^5.3.0"
94 |
95 | color-convert@^1.9.0:
96 | version "1.9.3"
97 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
98 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
99 | dependencies:
100 | color-name "1.1.3"
101 |
102 | color-name@1.1.3:
103 | version "1.1.3"
104 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
105 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
106 |
107 | commander@^2.12.1:
108 | version "2.20.3"
109 | resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
110 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
111 |
112 | concat-map@0.0.1:
113 | version "0.0.1"
114 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
115 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
116 |
117 | core-util-is@~1.0.0:
118 | version "1.0.2"
119 | resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
120 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
121 |
122 | debug@^2.2.0:
123 | version "2.6.9"
124 | resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
125 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
126 | dependencies:
127 | ms "2.0.0"
128 |
129 | diff@^4.0.1:
130 | version "4.0.2"
131 | resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"
132 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
133 |
134 | doctrine@^0.7.2:
135 | version "0.7.2"
136 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz"
137 | integrity sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=
138 | dependencies:
139 | esutils "^1.1.6"
140 | isarray "0.0.1"
141 |
142 | emojis-list@^3.0.0:
143 | version "3.0.0"
144 | resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz"
145 | integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
146 |
147 | enhanced-resolve@^3.0.0:
148 | version "3.4.1"
149 | resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz"
150 | integrity sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=
151 | dependencies:
152 | graceful-fs "^4.1.2"
153 | memory-fs "^0.4.0"
154 | object-assign "^4.0.1"
155 | tapable "^0.2.7"
156 |
157 | errno@^0.1.3:
158 | version "0.1.8"
159 | resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz"
160 | integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
161 | dependencies:
162 | prr "~1.0.1"
163 |
164 | escape-string-regexp@^1.0.5:
165 | version "1.0.5"
166 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
167 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
168 |
169 | esprima@^4.0.0:
170 | version "4.0.1"
171 | resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
172 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
173 |
174 | esutils@^1.1.6:
175 | version "1.1.6"
176 | resolved "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz"
177 | integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=
178 |
179 | fs.realpath@^1.0.0:
180 | version "1.0.0"
181 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
182 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
183 |
184 | function-bind@^1.1.1:
185 | version "1.1.1"
186 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
187 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
188 |
189 | glob@^7.1.1:
190 | version "7.1.6"
191 | resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
192 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
193 | dependencies:
194 | fs.realpath "^1.0.0"
195 | inflight "^1.0.4"
196 | inherits "2"
197 | minimatch "^3.0.4"
198 | once "^1.3.0"
199 | path-is-absolute "^1.0.0"
200 |
201 | graceful-fs@^4.1.2:
202 | version "4.2.4"
203 | resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz"
204 | integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
205 |
206 | has-flag@^3.0.0:
207 | version "3.0.0"
208 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
209 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
210 |
211 | has@^1.0.3:
212 | version "1.0.3"
213 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
214 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
215 | dependencies:
216 | function-bind "^1.1.1"
217 |
218 | ieee754@^1.2.1:
219 | version "1.2.1"
220 | resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
221 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
222 |
223 | inflight@^1.0.4:
224 | version "1.0.6"
225 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
226 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
227 | dependencies:
228 | once "^1.3.0"
229 | wrappy "1"
230 |
231 | inherits@2, inherits@~2.0.3:
232 | version "2.0.4"
233 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
234 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
235 |
236 | iota-array@^1.0.0:
237 | version "1.0.0"
238 | resolved "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz"
239 | integrity sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=
240 |
241 | is-buffer@^1.0.2:
242 | version "1.1.6"
243 | resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz"
244 | integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
245 |
246 | is-core-module@^2.1.0:
247 | version "2.2.0"
248 | resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz"
249 | integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
250 | dependencies:
251 | has "^1.0.3"
252 |
253 | isarray@0.0.1:
254 | version "0.0.1"
255 | resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
256 | integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
257 |
258 | isarray@~1.0.0:
259 | version "1.0.0"
260 | resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
261 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
262 |
263 | js-tokens@^4.0.0:
264 | version "4.0.0"
265 | resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
266 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
267 |
268 | js-yaml@^3.13.1:
269 | version "3.14.1"
270 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
271 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
272 | dependencies:
273 | argparse "^1.0.7"
274 | esprima "^4.0.0"
275 |
276 | json5@^1.0.1:
277 | version "1.0.1"
278 | resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz"
279 | integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
280 | dependencies:
281 | minimist "^1.2.0"
282 |
283 | loader-utils@^1.0.2:
284 | version "1.4.0"
285 | resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz"
286 | integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==
287 | dependencies:
288 | big.js "^5.2.2"
289 | emojis-list "^3.0.0"
290 | json5 "^1.0.1"
291 |
292 | memory-fs@^0.4.0:
293 | version "0.4.1"
294 | resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz"
295 | integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
296 | dependencies:
297 | errno "^0.1.3"
298 | readable-stream "^2.0.1"
299 |
300 | minimatch@^3.0.4:
301 | version "3.0.4"
302 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
303 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
304 | dependencies:
305 | brace-expansion "^1.1.7"
306 |
307 | minimist@^1.2.0, minimist@^1.2.5:
308 | version "1.2.5"
309 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
310 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
311 |
312 | mkdirp@^0.5.1:
313 | version "0.5.5"
314 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz"
315 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
316 | dependencies:
317 | minimist "^1.2.5"
318 |
319 | ms@2.0.0:
320 | version "2.0.0"
321 | resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
322 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
323 |
324 | mustache@^4.1.0:
325 | version "4.1.0"
326 | resolved "https://registry.npmjs.org/mustache/-/mustache-4.1.0.tgz"
327 | integrity sha512-0FsgP/WVq4mKyjolIyX+Z9Bd+3WS8GOwoUTyKXT5cTYMGeauNTi2HPCwERqseC1IHAy0Z7MDZnJBfjabd4O8GQ==
328 |
329 | mutable-buffer@2.0.3:
330 | version "2.0.3"
331 | resolved "https://registry.npmjs.org/mutable-buffer/-/mutable-buffer-2.0.3.tgz"
332 | integrity sha1-Z7ylVovxXT9gNftxbjiZ3ESQHIw=
333 |
334 | ndarray@^1.0.19:
335 | version "1.0.19"
336 | resolved "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz"
337 | integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==
338 | dependencies:
339 | iota-array "^1.0.0"
340 | is-buffer "^1.0.2"
341 |
342 | object-assign@^4.0.1:
343 | version "4.1.1"
344 | resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
345 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
346 |
347 | once@^1.3.0:
348 | version "1.4.0"
349 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
350 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
351 | dependencies:
352 | wrappy "1"
353 |
354 | pako@^1.0.5:
355 | version "1.0.11"
356 | resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
357 | integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
358 |
359 | path-is-absolute@^1.0.0:
360 | version "1.0.1"
361 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
362 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
363 |
364 | path-parse@^1.0.6:
365 | version "1.0.6"
366 | resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz"
367 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
368 |
369 | process-nextick-args@~2.0.0:
370 | version "2.0.1"
371 | resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
372 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
373 |
374 | prr@~1.0.1:
375 | version "1.0.1"
376 | resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz"
377 | integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
378 |
379 | readable-stream@^2.0.1:
380 | version "2.3.7"
381 | resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
382 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
383 | dependencies:
384 | core-util-is "~1.0.0"
385 | inherits "~2.0.3"
386 | isarray "~1.0.0"
387 | process-nextick-args "~2.0.0"
388 | safe-buffer "~5.1.1"
389 | string_decoder "~1.1.1"
390 | util-deprecate "~1.0.1"
391 |
392 | resolve@^1.3.2:
393 | version "1.19.0"
394 | resolved "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz"
395 | integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
396 | dependencies:
397 | is-core-module "^2.1.0"
398 | path-parse "^1.0.6"
399 |
400 | safe-buffer@~5.1.0, safe-buffer@~5.1.1:
401 | version "5.1.2"
402 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
403 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
404 |
405 | semver@^5.0.1, semver@^5.3.0:
406 | version "5.7.1"
407 | resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
408 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
409 |
410 | sprintf-js@~1.0.2:
411 | version "1.0.3"
412 | resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
413 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
414 |
415 | string_decoder@~1.1.1:
416 | version "1.1.1"
417 | resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
418 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
419 | dependencies:
420 | safe-buffer "~5.1.0"
421 |
422 | supports-color@^5.3.0:
423 | version "5.5.0"
424 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
425 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
426 | dependencies:
427 | has-flag "^3.0.0"
428 |
429 | tapable@^0.2.7:
430 | version "0.2.9"
431 | resolved "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz"
432 | integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==
433 |
434 | ts-loader@^2.3.4:
435 | version "2.3.7"
436 | resolved "https://registry.npmjs.org/ts-loader/-/ts-loader-2.3.7.tgz"
437 | integrity sha512-8t3bu2FcEkXb+D4L+Cn8qiK2E2C6Ms4/GQChvz6IMbVurcFHLXrhW4EMtfaol1a1ASQACZGDUGit4NHnX9g7hQ==
438 | dependencies:
439 | chalk "^2.0.1"
440 | enhanced-resolve "^3.0.0"
441 | loader-utils "^1.0.2"
442 | semver "^5.0.1"
443 |
444 | tslib@^1.0.0, tslib@^1.8.0, tslib@^1.8.1:
445 | version "1.14.1"
446 | resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
447 | integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
448 |
449 | tslint-eslint-rules@^4.1.1:
450 | version "4.1.1"
451 | resolved "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz"
452 | integrity sha1-fDDniC8mvCdr/5HSOEl1xp2viLo=
453 | dependencies:
454 | doctrine "^0.7.2"
455 | tslib "^1.0.0"
456 | tsutils "^1.4.0"
457 |
458 | tslint@^5.7.0:
459 | version "5.20.1"
460 | resolved "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz"
461 | integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==
462 | dependencies:
463 | "@babel/code-frame" "^7.0.0"
464 | builtin-modules "^1.1.1"
465 | chalk "^2.3.0"
466 | commander "^2.12.1"
467 | diff "^4.0.1"
468 | glob "^7.1.1"
469 | js-yaml "^3.13.1"
470 | minimatch "^3.0.4"
471 | mkdirp "^0.5.1"
472 | resolve "^1.3.2"
473 | semver "^5.3.0"
474 | tslib "^1.8.0"
475 | tsutils "^2.29.0"
476 |
477 | tsutils@^1.4.0:
478 | version "1.9.1"
479 | resolved "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz"
480 | integrity sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=
481 |
482 | tsutils@^2.29.0:
483 | version "2.29.0"
484 | resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz"
485 | integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
486 | dependencies:
487 | tslib "^1.8.1"
488 |
489 | typescript@^4.1.3:
490 | version "4.1.3"
491 | resolved "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz"
492 | integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
493 |
494 | upng-js@2.1.0:
495 | version "2.1.0"
496 | resolved "https://registry.yarnpkg.com/upng-js/-/upng-js-2.1.0.tgz#7176e73973db361ca95d0fa14f958385db6b9dd2"
497 | integrity sha512-d3xzZzpMP64YkjP5pr8gNyvBt7dLk/uGI67EctzDuVp4lCZyVMo0aJO6l/VDlgbInJYDY6cnClLoBp29eKWI6g==
498 | dependencies:
499 | pako "^1.0.5"
500 |
501 | util-deprecate@~1.0.1:
502 | version "1.0.2"
503 | resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
504 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
505 |
506 | wrappy@1:
507 | version "1.0.2"
508 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
509 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
510 |
511 | xml-parser@^1.2.1:
512 | version "1.2.1"
513 | resolved "https://registry.npmjs.org/xml-parser/-/xml-parser-1.2.1.tgz"
514 | integrity sha1-wx9MNPKXXbgq0BMiISBZJzYVb80=
515 | dependencies:
516 | debug "^2.2.0"
517 |
--------------------------------------------------------------------------------