From 6b5ed1fd98c94da3ceab804cc5b123d1fd6a28ec Mon Sep 17 00:00:00 2001 From: Cellivar <1441553+Cellivar@users.noreply.github.com> Date: Mon, 8 Jan 2024 06:46:35 -0800 Subject: [PATCH] v2: Ignore other devices (#48) An early design oversight has lead to a v2 release. The `connectedDevice` event performs no checking to ensure the device that connected is one the library cares about. I never tested the scenario of connecting something other than a bunch of laser printers at the same time until now. Since that required an API change I figured I'd add as much API-breaking-changes in one go as I could. Anyway. This includes a switch to Vite, which I've found a VERY pleasant ecosystem to work within for building the package. ## Breaking changes: * USBDeviceManager is the new manager class. * LabelPrinter is the new Printer class. * A few other ancillary classes became interfaces and names changes slightly. The types should be self-explanatory to follow. --- .editorconfig | 2 +- .eslintrc | 33 - .eslintrc.cjs | 8 + .github/workflows/build_npm.yml | 29 +- .github/workflows/publish_npm.yml | 8 +- .gitignore | 1 + .npmignore | 4 - .prettierrc | 7 - demo/advanced.html | 252 +- demo-sw.js => demo/demo-sw.js | 8 +- demo/index.html | 299 +- demo/test_advanced.ts | 475 + demo/test_index.ts | 437 + demo/ts-browser.js | 2 +- jest.config.ts | 18 - package-lock.json | 9408 ++++++----------- package.json | 70 +- src/Color.ts | 269 - {test => src}/Documents/BitmapGRF.test.ts | 50 +- src/Documents/BitmapGRF.ts | 13 +- src/Documents/Commands.ts | 776 +- src/Documents/ConfigDocument.ts | 508 +- src/Documents/Document.ts | 108 +- src/Documents/LabelDocument.ts | 369 +- src/Documents/ReadyToPrintDocuments.ts | 164 +- src/Documents/index.ts | 6 + src/NumericRange.test.ts | 16 + src/NumericRange.ts | 27 + src/PrinterUsbManager.ts | 263 +- .../Communication/DeviceCommunication.ts | 92 + .../Communication/LineBreakTransformer.ts | 20 +- .../Communication/PrinterCommunication.ts | 58 - .../Communication/UsbPrinterDeviceChannel.ts | 430 +- src/Printers/Configuration/MediaOptions.ts | 327 +- src/Printers/Configuration/PrinterOptions.ts | 224 +- .../Configuration/SerialPortSettings.ts | 100 +- .../Languages/EplPrinterCommandSet.test.ts | 31 +- .../Languages/EplPrinterCommandSet.ts | 1059 +- src/Printers/Languages/PrinterCommandSet.ts | 547 +- .../Languages/ZplPrinterCommandSet.ts | 1030 +- src/Printers/Models/EplPrinterModels.ts | 72 +- src/Printers/Models/PrinterModel.ts | 254 +- src/Printers/Models/PrinterModelDb.ts | 167 +- src/Printers/Printer.ts | 425 +- src/Printers/PrinterCommunicationOptions.ts | 38 - src/Printers/index.ts | 13 + src/WebZlpError.ts | 8 +- src/index.ts | 21 +- tsconfig.json | 32 +- vite.config.ts | 25 + 50 files changed, 8444 insertions(+), 10159 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.cjs delete mode 100644 .npmignore delete mode 100644 .prettierrc rename demo-sw.js => demo/demo-sw.js (94%) create mode 100644 demo/test_advanced.ts create mode 100644 demo/test_index.ts delete mode 100644 jest.config.ts delete mode 100644 src/Color.ts rename {test => src}/Documents/BitmapGRF.test.ts (85%) create mode 100644 src/Documents/index.ts create mode 100644 src/NumericRange.test.ts create mode 100644 src/Printers/Communication/DeviceCommunication.ts delete mode 100644 src/Printers/Communication/PrinterCommunication.ts rename {test => src}/Printers/Languages/EplPrinterCommandSet.test.ts (83%) delete mode 100644 src/Printers/PrinterCommunicationOptions.ts create mode 100644 src/Printers/index.ts create mode 100644 vite.config.ts diff --git a/.editorconfig b/.editorconfig index 74aca92..d4221b7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,4 +7,4 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true indent_style = space -indent_size = 4 \ No newline at end of file +indent_size = 2 \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 7f19aea..0000000 --- a/.eslintrc +++ /dev/null @@ -1,33 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint", - "prettier" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "rules": { - "@typescript-eslint/naming-convention": [ - "error" - ], - "no-fallthrough": 0, - "prettier/prettier": [ - "error", - { - "printWidth": 100, - "endOfLine": "auto" - } - ], - "linebreak-style": 0 - }, - "ignorePatterns": [ - "dist/*", - "demo/ts-browser.js", - "demo-sw.js" - ] -} \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..5c1b077 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,8 @@ +/* eslint-env node */ +module.exports = { + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + root: true, + ignorePatterns: ['**/node_modules/**'] +}; diff --git a/.github/workflows/build_npm.yml b/.github/workflows/build_npm.yml index 81095d8..5cb532e 100644 --- a/.github/workflows/build_npm.yml +++ b/.github/workflows/build_npm.yml @@ -1,5 +1,9 @@ name: Build +permissions: + issues: write + pull-requests: write + on: pull_request: push: @@ -9,23 +13,14 @@ on: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] steps: - - uses: actions/checkout@v2 - - name: Build on Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: 20 - run: npm ci --ignore-scripts - - uses: mattallty/jest-github-action@v1 - if: github.event_name == 'pull_request' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: mattallty/jest-github-action@v1 - if: github.event_name == 'push' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - coverage-comment: false + - name: 'Test' + run: npx vitest --coverage.enabled true + - name: 'Report Coverage' + if: ${{ !cancelled() }} + uses: davelosert/vitest-coverage-report-action@v2 diff --git a/.github/workflows/publish_npm.yml b/.github/workflows/publish_npm.yml index d9b8990..3a8455e 100644 --- a/.github/workflows/publish_npm.yml +++ b/.github/workflows/publish_npm.yml @@ -1,17 +1,19 @@ name: Publish Package to npmjs + on: release: types: [created] + jobs: build: runs-on: ubuntu-latest environment: publish steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # Setup .npmrc file to publish to npm - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: '18.x' + node-version: 20 registry-url: 'https://registry.npmjs.org' - run: npm ci --ignore-scripts - run: npm run build diff --git a/.gitignore b/.gitignore index ef229ed..8c2b29b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coverage/ dist/ node_modules/ +tsconfig.tsbuildinfo diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 91c80f1..0000000 --- a/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -.github/ -test/ -coverage/ -jest.config.jest diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index a0510ff..0000000 --- a/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "semi": true, - "trailingComma": "none", - "singleQuote": true, - "printWidth": 100, - "endOfLine": "auto" -} \ No newline at end of file diff --git a/demo/advanced.html b/demo/advanced.html index 192927f..e5d1da9 100644 --- a/demo/advanced.html +++ b/demo/advanced.html @@ -40,7 +40,7 @@ document.getElementById('loadingIndicator').classList.add('d-none'); // This bit detects if the browser supports WebUSB, displaying a warning if not. - if (navigator.usb == null) { + if (navigator.usb === undefined) { document.getElementById('browserNoWebUsb').classList.remove('d-none'); } @@ -65,43 +65,45 @@ diff --git a/demo-sw.js b/demo/demo-sw.js similarity index 94% rename from demo-sw.js rename to demo/demo-sw.js index 703d2fb..3f833fb 100644 --- a/demo-sw.js +++ b/demo/demo-sw.js @@ -1,5 +1,5 @@ // Has to be a hard version so the URL doesn't redirect, which prevents loading. -importScripts('https://unpkg.com/typescript@4.9.3/lib/typescript.js'); +importScripts('https://unpkg.com/typescript@5.2.2/lib/typescript.js'); const log = (...obj) => console.log('SHENANIGANS', ...obj); @@ -12,6 +12,10 @@ self.addEventListener('activate', () => self.clients.claim()); // Intercept fetch requests for modules and compile the intercepted typescript. self.addEventListener('fetch', (event) => { + if (!event.request.url.startsWith('https://')) { + return; + } + // Start off easy: if it's a request for a TS file, transpile it. if (event.request.url.endsWith('.ts')) { log('Fetching', event.request.url, 'as just typescript'); @@ -102,7 +106,7 @@ const transpileTypeScript = async (requestUrl) => { }; const transpiledResponse = new Response(transpiledCode, responseOptions); - if (!requestUrl.startsWith('https://localhost')) { + if (!requestUrl.startsWith('https://localhost') && requestUrl.startsWith('https://')) { typescriptCache.put(requestUrl, transpiledResponse.clone()); } diff --git a/demo/index.html b/demo/index.html index 97d7a3c..0847503 100644 --- a/demo/index.html +++ b/demo/index.html @@ -50,7 +50,7 @@ document.getElementById('loadingIndicator').classList.add('d-none'); // This bit detects if the browser supports WebUSB, displaying a warning if not. - if (navigator.usb == null) { + if (navigator.usb === undefined) { document.getElementById('browserNoWebUsb').classList.remove('d-none'); } @@ -75,42 +75,45 @@ diff --git a/demo/test_advanced.ts b/demo/test_advanced.ts new file mode 100644 index 0000000..0939d35 --- /dev/null +++ b/demo/test_advanced.ts @@ -0,0 +1,475 @@ +import * as WebLabel from '../src/index.js'; +// This file exists to test the index.html's typescript. Unfortunately there isn't +// a good way to configure Visual Studio Code to, well, treat it as typescript. +//////////////////////////////////////////////////////////////////////////////// + +// First import the lib! +//import * as WebLabel from 'web-receiptline-printer'; + +// For this demo we're going to make use of the USB printer manager +// so it can take care of concerns like the USB connect and disconnect events. + +const printerMgr = new WebLabel.UsbDeviceManager( + window.navigator.usb, + WebLabel.LabelPrinter.fromUSBDevice, + { + // Enable debugging, so the dev console can fill up with interesting messages! + debug: true, + requestOptions: { + // Limit the USB devices we try to connect to. + filters: [ + { + vendorId: 0x0A5F // Zebra + } + ] + } + } +) + +// We'll wire up some basic event listeners to the printer manager. +// First, a button to prompt a user to add a printer. +const addPrinterBtn = document.getElementById('addprinter')!; +addPrinterBtn.addEventListener('click', async () => printerMgr.promptForNewDevice()); + +// Next a button to manually refresh all printers, just in case. +const refreshPrinterBtn = document.getElementById('refreshPrinters')!; +refreshPrinterBtn.addEventListener('click', async () => printerMgr.forceReconnect()); + +// Next we wire up some events on the PrinterUsbManager itself. +printerMgr.addEventListener('connectedDevice', ({ detail }) => { + const printer = detail.device; + console.log('New printer is a', printer.printerModel.model); + const config = printer.printerOptions; + console.log('Printer darkness is', config.darknessPercent, 'percent'); + console.log('Printer speed is', WebLabel.PrintSpeed[config.speed.printSpeed]); + console.log( + 'Label is', + config.labelWidthInches, + 'in wide and', + config.labelHeightInches, + 'in tall, with a gap of', + config.labelGapInches, + 'in.'); + console.log('Printer media handling is', WebLabel.LabelMediaGapDetectionMode[config.labelGapDetectMode]); +}); + +// There's also an event that will tell you when a printer disconnects. +printerMgr.addEventListener('disconnectedDevice', ({ detail }) => { + const printer = detail.device; + console.log('Lost printer', printer.printerModel.model, 'serial', printer.printerOptions.serialNumber); +}); + +// When the browser first loaded the page any previously connected printers would have caused +// a connection event. Our listener wasn't listening yet so missed it. +// It's good practice to force a reconnect once your event handlers are ready. +// We're going to skip this for now though, because we want it to happen after the app is ready. +//await printerMgr.reconnectAllPrinters(); + +// And that's all there is to setup! The page can now talk to printers. +// If you're using a chromebook this should just work. If you're on Windows +// you might need to do some driver setup, see the repo README for more details. + +// The rest of this demo is an example of a basic label generator app. + +// The app's logic is wrapped in a class just for ease of reading. +class BasicLabelDesignerApp { + constructor( + private manager: WebLabel.UsbDeviceManager, + private btnContainer: HTMLElement, + private labelForm: HTMLElement, + private labelFormInstructions: HTMLElement, + private configModal: HTMLElement + ) { + // Based on the containers, map the various listeners. + this.configModalHandle = new bootstrap.Modal(this.configModal); + this.configModal + .querySelector('form')! + .addEventListener('submit', this.updatePrinterConfig.bind(this)); + this.labelForm.addEventListener('blur', this.renderTextForm.bind(this)); + this.labelForm.addEventListener('keyup', this.renderTextForm.bind(this)); + + // Add a second set of event listeners for printer connect and disconnect to redraw + // the printer list when it changes. + this.manager.addEventListener('connectedDevice', () => { + this.activePrinterIndex = -1; + this.redrawPrinterButtons(); + }); + this.manager.addEventListener('disconnectedDevice', () => { + this.activePrinterIndex = -1; + this.redrawPrinterButtons(); + }); + + // Here's a nice font with a great set of emoji that work well for monochrome printing. + // The text font is fairly basic though, so we would like to use only the emoji out + // of this font and use a basic sans-serif font for regular text. + // https://fonts.google.com/noto/specimen/Noto+Emoji + const emojiFontName = 'noto-emoji'; + + // We can accomplish this with the unicodeRange property of our FontFace. We just + // need to list EVERY SINGLE EMOJI UNICODE RANGE to make it work. Fortunately someone + // has done this already: https://github.com/fraction/emoji-unicode-range + const emojiUnicodeRange = 'U+00A9,U+00AE,U+203C,U+2049,U+2122,U+2139,U+2194-2199,U+21A9-21AA,U+231A-231B,U+2328,U+23CF,U+23E9-23F3,U+23F8-23FA,U+24C2,U+25AA-25AB,U+25B6,U+25C0,U+25FB-25FE,U+2600-2604,U+260E,U+2611,U+2614-2615,U+2618,U+261D,U+2620,U+2622-2623,U+2626,U+262A,U+262E-262F,U+2638-263A,U+2640,U+2642,U+2648-2653,U+265F-2660,U+2663,U+2665-2666,U+2668,U+267B,U+267E-267F,U+2692-2697,U+2699,U+269B-269C,U+26A0-26A1,U+26AA-26AB,U+26B0-26B1,U+26BD-26BE,U+26C4-26C5,U+26C8,U+26CE,U+26CF,U+26D1,U+26D3-26D4,U+26E9-26EA,U+26F0-26F5,U+26F7-26FA,U+26FD,U+2702,U+2705,U+2708-2709,U+270A-270B,U+270C-270D,U+270F,U+2712,U+2714,U+2716,U+271D,U+2721,U+2728,U+2733-2734,U+2744,U+2747,U+274C,U+274E,U+2753-2755,U+2757,U+2763-2764,U+2795-2797,U+27A1,U+27B0,U+27BF,U+2934-2935,U+2B05-2B07,U+2B1B-2B1C,U+2B50,U+2B55,U+3030,U+303D,U+3297,U+3299,U+1F004,U+1F0CF,U+1F170-1F171,U+1F17E,U+1F17F,U+1F18E,U+1F191-1F19A,U+1F1E6-1F1FF,U+1F201-1F202,U+1F21A,U+1F22F,U+1F232-1F23A,U+1F250-1F251,U+1F300-1F320,U+1F321,U+1F324-1F32C,U+1F32D-1F32F,U+1F330-1F335,U+1F336,U+1F337-1F37C,U+1F37D,U+1F37E-1F37F,U+1F380-1F393,U+1F396-1F397,U+1F399-1F39B,U+1F39E-1F39F,U+1F3A0-1F3C4,U+1F3C5,U+1F3C6-1F3CA,U+1F3CB-1F3CE,U+1F3CF-1F3D3,U+1F3D4-1F3DF,U+1F3E0-1F3F0,U+1F3F3-1F3F5,U+1F3F7,U+1F3F8-1F3FF,U+1F400-1F43E,U+1F43F,U+1F440,U+1F441,U+1F442-1F4F7,U+1F4F8,U+1F4F9-1F4FC,U+1F4FD,U+1F4FF,U+1F500-1F53D,U+1F549-1F54A,U+1F54B-1F54E,U+1F550-1F567,U+1F56F-1F570,U+1F573-1F579,U+1F57A,U+1F587,U+1F58A-1F58D,U+1F590,U+1F595-1F596,U+1F5A4,U+1F5A5,U+1F5A8,U+1F5B1-1F5B2,U+1F5BC,U+1F5C2-1F5C4,U+1F5D1-1F5D3,U+1F5DC-1F5DE,U+1F5E1,U+1F5E3,U+1F5E8,U+1F5EF,U+1F5F3,U+1F5FA,U+1F5FB-1F5FF,U+1F600,U+1F601-1F610,U+1F611,U+1F612-1F614,U+1F615,U+1F616,U+1F617,U+1F618,U+1F619,U+1F61A,U+1F61B,U+1F61C-1F61E,U+1F61F,U+1F620-1F625,U+1F626-1F627,U+1F628-1F62B,U+1F62C,U+1F62D,U+1F62E-1F62F,U+1F630-1F633,U+1F634,U+1F635-1F640,U+1F641-1F642,U+1F643-1F644,U+1F645-1F64F,U+1F680-1F6C5,U+1F6CB-1F6CF,U+1F6D0,U+1F6D1-1F6D2,U+1F6D5,U+1F6E0-1F6E5,U+1F6E9,U+1F6EB-1F6EC,U+1F6F0,U+1F6F3,U+1F6F4-1F6F6,U+1F6F7-1F6F8,U+1F6F9,U+1F6FA,U+1F7E0-1F7EB,U+1F90D-1F90F,U+1F910-1F918,U+1F919-1F91E,U+1F91F,U+1F920-1F927,U+1F928-1F92F,U+1F930,U+1F931-1F932,U+1F933-1F93A,U+1F93C-1F93E,U+1F93F,U+1F940-1F945,U+1F947-1F94B,U+1F94C,U+1F94D-1F94F,U+1F950-1F95E,U+1F95F-1F96B,U+1F96C-1F970,U+1F971,U+1F973-1F976,U+1F97A,U+1F97B,U+1F97C-1F97F,U+1F980-1F984,U+1F985-1F991,U+1F992-1F997,U+1F998-1F9A2,U+1F9A5-1F9AA,U+1F9AE-1F9AF,U+1F9B0-1F9B9,U+1F9BA-1F9BF,U+1F9C0,U+1F9C1-1F9C2,U+1F9C3-1F9CA,U+1F9CD-1F9CF,U+1F9D0-1F9E6,U+1F9E7-1F9FF,U+1FA70-1FA73,U+1FA78-1FA7A,U+1FA80-1FA82,U+1FA90-1FA95,U+231A-231B,U+23E9-23EC,U+23F0,U+23F3,U+25FD-25FE,U+2614-2615,U+2648-2653,U+267F,U+2693,U+26A1,U+26AA-26AB,U+26BD-26BE,U+26C4-26C5,U+26CE,U+26D4,U+26EA,U+26F2-26F3,U+26F5,U+26FA,U+26FD,U+2705,U+270A-270B,U+2728,U+274C,U+274E,U+2753-2755,U+2757,U+2795-2797,U+27B0,U+27BF,U+2B1B-2B1C,U+2B50,U+2B55,U+1F004,U+1F0CF,U+1F18E,U+1F191-1F19A,U+1F1E6-1F1FF,U+1F201,U+1F21A,U+1F22F,U+1F232-1F236,U+1F238-1F23A,U+1F250-1F251,U+1F300-1F320,U+1F32D-1F32F,U+1F330-1F335,U+1F337-1F37C,U+1F37E-1F37F,U+1F380-1F393,U+1F3A0-1F3C4,U+1F3C5,U+1F3C6-1F3CA,U+1F3CF-1F3D3,U+1F3E0-1F3F0,U+1F3F4,U+1F3F8-1F3FF,U+1F400-1F43E,U+1F440,U+1F442-1F4F7,U+1F4F8,U+1F4F9-1F4FC,U+1F4FF,U+1F500-1F53D,U+1F54B-1F54E,U+1F550-1F567,U+1F57A,U+1F595-1F596,U+1F5A4,U+1F5FB-1F5FF,U+1F600,U+1F601-1F610,U+1F611,U+1F612-1F614,U+1F615,U+1F616,U+1F617,U+1F618,U+1F619,U+1F61A,U+1F61B,U+1F61C-1F61E,U+1F61F,U+1F620-1F625,U+1F626-1F627,U+1F628-1F62B,U+1F62C,U+1F62D,U+1F62E-1F62F,U+1F630-1F633,U+1F634,U+1F635-1F640,U+1F641-1F642,U+1F643-1F644,U+1F645-1F64F,U+1F680-1F6C5,U+1F6CC,U+1F6D0,U+1F6D1-1F6D2,U+1F6D5,U+1F6EB-1F6EC,U+1F6F4-1F6F6,U+1F6F7-1F6F8,U+1F6F9,U+1F6FA,U+1F7E0-1F7EB,U+1F90D-1F90F,U+1F910-1F918,U+1F919-1F91E,U+1F91F,U+1F920-1F927,U+1F928-1F92F,U+1F930,U+1F931-1F932,U+1F933-1F93A,U+1F93C-1F93E,U+1F93F,U+1F940-1F945,U+1F947-1F94B,U+1F94C,U+1F94D-1F94F,U+1F950-1F95E,U+1F95F-1F96B,U+1F96C-1F970,U+1F971,U+1F973-1F976,U+1F97A,U+1F97B,U+1F97C-1F97F,U+1F980-1F984,U+1F985-1F991,U+1F992-1F997,U+1F998-1F9A2,U+1F9A5-1F9AA,U+1F9AE-1F9AF,U+1F9B0-1F9B9,U+1F9BA-1F9BF,U+1F9C0,U+1F9C1-1F9C2,U+1F9C3-1F9CA,U+1F9CD-1F9CF,U+1F9D0-1F9E6,U+1F9E7-1F9FF,U+1FA70-1FA73,U+1FA78-1FA7A,U+1FA80-1FA82,U+1FA90-1FA95,U+1F3FB-1F3FF,U+261D,U+26F9,U+270A-270B,U+270C-270D,U+1F385,U+1F3C2-1F3C4,U+1F3C7,U+1F3CA,U+1F3CB-1F3CC,U+1F442-1F443,U+1F446-1F450,U+1F466-1F478,U+1F47C,U+1F481-1F483,U+1F485-1F487,U+1F48F,U+1F491,U+1F4AA,U+1F574-1F575,U+1F57A,U+1F590,U+1F595-1F596,U+1F645-1F647,U+1F64B-1F64F,U+1F6A3,U+1F6B4-1F6B6,U+1F6C0,U+1F6CC,U+1F90F,U+1F918,U+1F919-1F91E,U+1F91F,U+1F926,U+1F930,U+1F931-1F932,U+1F933-1F939,U+1F93C-1F93E,U+1F9B5-1F9B6,U+1F9B8-1F9B9,U+1F9BB,U+1F9CD-1F9CF,U+1F9D1-1F9DD,U+0023,U+002A,U+0030-0039,U+200D,U+20E3,U+FE0F,U+1F1E6-1F1FF,U+1F3FB-1F3FF,U+1F9B0-1F9B3,U+E0020-E007F,U+00A9,U+00AE,U+203C,U+2049,U+2122,U+2139,U+2194-2199,U+21A9-21AA,U+231A-231B,U+2328,U+2388,U+23CF,U+23E9-23F3,U+23F8-23FA,U+24C2,U+25AA-25AB,U+25B6,U+25C0,U+25FB-25FE,U+2600-2605,U+2607-2612,U+2614-2615,U+2616-2617,U+2618,U+2619,U+261A-266F,U+2670-2671,U+2672-267D,U+267E-267F,U+2680-2685,U+2690-2691,U+2692-269C,U+269D,U+269E-269F,U+26A0-26A1,U+26A2-26B1,U+26B2,U+26B3-26BC,U+26BD-26BF,U+26C0-26C3,U+26C4-26CD,U+26CE,U+26CF-26E1,U+26E2,U+26E3,U+26E4-26E7,U+26E8-26FF,U+2700,U+2701-2704,U+2705,U+2708-2709,U+270A-270B,U+270C-2712,U+2714,U+2716,U+271D,U+2721,U+2728,U+2733-2734,U+2744,U+2747,U+274C,U+274E,U+2753-2755,U+2757,U+2763-2767,U+2795-2797,U+27A1,U+27B0,U+27BF,U+2934-2935,U+2B05-2B07,U+2B1B-2B1C,U+2B50,U+2B55,U+3030,U+303D,U+3297,U+3299,U+1F000-1F02B,U+1F02C-1F02F,U+1F030-1F093,U+1F094-1F09F,U+1F0A0-1F0AE,U+1F0AF-1F0B0,U+1F0B1-1F0BE,U+1F0BF,U+1F0C0,U+1F0C1-1F0CF,U+1F0D0,U+1F0D1-1F0DF,U+1F0E0-1F0F5,U+1F0F6-1F0FF,U+1F10D-1F10F,U+1F12F,U+1F16C,U+1F16D-1F16F,U+1F170-1F171,U+1F17E,U+1F17F,U+1F18E,U+1F191-1F19A,U+1F1AD-1F1E5,U+1F201-1F202,U+1F203-1F20F,U+1F21A,U+1F22F,U+1F232-1F23A,U+1F23C-1F23F,U+1F249-1F24F,U+1F250-1F251,U+1F252-1F25F,U+1F260-1F265,U+1F266-1F2FF,U+1F300-1F320,U+1F321-1F32C,U+1F32D-1F32F,U+1F330-1F335,U+1F336,U+1F337-1F37C,U+1F37D,U+1F37E-1F37F,U+1F380-1F393,U+1F394-1F39F,U+1F3A0-1F3C4,U+1F3C5,U+1F3C6-1F3CA,U+1F3CB-1F3CE,U+1F3CF-1F3D3,U+1F3D4-1F3DF,U+1F3E0-1F3F0,U+1F3F1-1F3F7,U+1F3F8-1F3FA,U+1F400-1F43E,U+1F43F,U+1F440,U+1F441,U+1F442-1F4F7,U+1F4F8,U+1F4F9-1F4FC,U+1F4FD-1F4FE,U+1F4FF,U+1F500-1F53D,U+1F546-1F54A,U+1F54B-1F54F,U+1F550-1F567,U+1F568-1F579,U+1F57A,U+1F57B-1F5A3,U+1F5A4,U+1F5A5-1F5FA,U+1F5FB-1F5FF,U+1F600,U+1F601-1F610,U+1F611,U+1F612-1F614,U+1F615,U+1F616,U+1F617,U+1F618,U+1F619,U+1F61A,U+1F61B,U+1F61C-1F61E,U+1F61F,U+1F620-1F625,U+1F626-1F627,U+1F628-1F62B,U+1F62C,U+1F62D,U+1F62E-1F62F,U+1F630-1F633,U+1F634,U+1F635-1F640,U+1F641-1F642,U+1F643-1F644,U+1F645-1F64F,U+1F680-1F6C5,U+1F6C6-1F6CF,U+1F6D0,U+1F6D1-1F6D2,U+1F6D3-1F6D4,U+1F6D5,U+1F6D6-1F6DF,U+1F6E0-1F6EC,U+1F6ED-1F6EF,U+1F6F0-1F6F3,U+1F6F4-1F6F6,U+1F6F7-1F6F8,U+1F6F9,U+1F6FA,U+1F6FB-1F6FF,U+1F774-1F77F,U+1F7D5-1F7D8,U+1F7D9-1F7DF,U+1F7E0-1F7EB,U+1F7EC-1F7FF,U+1F80C-1F80F,U+1F848-1F84F,U+1F85A-1F85F,U+1F888-1F88F,U+1F8AE-1F8FF,U+1F90C,U+1F90D-1F90F,U+1F910-1F918,U+1F919-1F91E,U+1F91F,U+1F920-1F927,U+1F928-1F92F,U+1F930,U+1F931-1F932,U+1F933-1F93A,U+1F93C-1F93E,U+1F93F,U+1F940-1F945,U+1F947-1F94B,U+1F94C,U+1F94D-1F94F,U+1F950-1F95E,U+1F95F-1F96B,U+1F96C-1F970,U+1F971,U+1F972,U+1F973-1F976,U+1F977-1F979,U+1F97A,U+1F97B,U+1F97C-1F97F,U+1F980-1F984,U+1F985-1F991,U+1F992-1F997,U+1F998-1F9A2,U+1F9A3-1F9A4,U+1F9A5-1F9AA,U+1F9AB-1F9AD,U+1F9AE-1F9AF,U+1F9B0-1F9B9,U+1F9BA-1F9BF,U+1F9C0,U+1F9C1-1F9C2,U+1F9C3-1F9CA,U+1F9CB-1F9CC,U+1F9CD-1F9CF,U+1F9D0-1F9E6,U+1F9E7-1F9FF,U+1FA00-1FA53,U+1FA54-1FA5F,U+1FA60-1FA6D,U+1FA6E-1FA6F,U+1FA70-1FA73,U+1FA74-1FA77,U+1FA78-1FA7A,U+1FA7B-1FA7F,U+1FA80-1FA82,U+1FA83-1FA8F,U+1FA90-1FA95,U+1FA96-1FFFD'; + + // And then we can use that range with our font when we load it. + const emojiOnlyFont = new FontFace(emojiFontName, 'url(fonts/NotoEmoji-Regular.ttf)', { + unicodeRange: emojiUnicodeRange, + }); + emojiOnlyFont.load().then(() => { + document.fonts.add(emojiOnlyFont); + }); + // We then set our fallback font as part of the font family we use in the canvas. + // This order matters, latter fonts will use the unicodeRange to override earlier fonts. + this.fontName = `Sans-serif, ${emojiFontName}` + } + + // Some storage fields and utility properties + private fontName: string; + private configModalHandle: any; + + get printers(): readonly WebLabel.LabelPrinter[] { + return this.manager.devices; + } + + // Track which printer is currently selected for operations + private _activePrinter = 0; + get activePrinter(): WebLabel.LabelPrinter | undefined { + return this._activePrinter < 0 || this._activePrinter > this.printers.length + ? undefined + : this.printers[this._activePrinter]; + } + set activePrinterIndex(printerIdx: number) { + this._activePrinter = printerIdx; + this.redrawTextCanvas(); + } + + /** Initialize the app */ + public async init() { + this.redrawPrinterButtons(); + this.redrawTextCanvas(); + } + + /** Display the configuration for a printer. */ + public showConfigModal(printer: WebLabel.LabelPrinter, printerIdx: number) { + if (printer == undefined) { + return; + } + const config = printer.printerOptions; + + // Translate the available speeds to options to be selected + const speedSelect = this.configModal.querySelector('#modalSpeed')!; + speedSelect.innerHTML = ''; + const speedTable = printer.printerModel.speedTable as ReadonlyMap; + for (const [key, val] of speedTable) { + // Skip utility values, so long as there's more than the defaults. + // Mobile printers *only* support auto, for example. + if ((speedTable.size > 3) + && (key === WebLabel.PrintSpeed.ipsAuto + || key === WebLabel.PrintSpeed.ipsPrinterMax + || key === WebLabel.PrintSpeed.ipsPrinterMin + )) { + continue; + } + const opt = document.createElement('option'); + opt.value = key; + opt.innerHTML = WebLabel.PrintSpeed[key].substring(3).replaceAll('_', '.') + ' ips'; + speedSelect.appendChild(opt); + } + speedSelect.value = config.speed.printSpeed; + + const mediaSelect = this.configModal.querySelector('#modalMediaType')!; + switch (config.labelGapDetectMode) { + case WebLabel.LabelMediaGapDetectionMode.continuous: + mediaSelect.value = "continuous"; + break; + default: + case WebLabel.LabelMediaGapDetectionMode.webSensing: + mediaSelect.value = "gap"; + break; + case WebLabel.LabelMediaGapDetectionMode.markSensing: + mediaSelect.value = "mark"; + break; + } + + this.configModal.querySelector('#modalPrinterIndex')!.value = config.serialNumber; + this.configModal.querySelector('#modalPrinterIndexText')!.textContent = printerIdx; + this.configModal.querySelector('#modalLabelWidth')!.value = config.labelWidthInches; + this.configModal.querySelector('#modalLabelHeight')!.value = config.labelHeightInches; + this.configModal.querySelector('#modalDarkness')!.value = config.darknessPercent; + this.configModal.querySelector('#modalLabelOffsetLeft')!.value = config.labelPrintOriginOffsetDots.left; + this.configModal.querySelector('#modalLabelOffsetTop')!.value = config.labelPrintOriginOffsetDots.top; + this.configModalHandle.show(); + } + + /** Erase and re-draw the list of printer buttons in the UI. */ + private redrawPrinterButtons() { + this.btnContainer.innerHTML = ''; + this.printers.forEach((printer, idx) => this.drawPrinterButton(printer, idx)); + } + + /** Highlight only the currently selected printer. */ + private redrawPrinterButtonHighlights() { + this.printers.forEach((printer, idx) => { + const highlight = this._activePrinter == idx ? "var(--bs-blue)" : "transparent"; + const element = document.getElementById(`printer_${idx}`)!; + element.style.background = `linear-gradient(to right, ${highlight}, ${highlight}, grey, grey)`; + }); + } + + /** Add a printer's button UI to the list of printers. */ + private drawPrinterButton(printer: WebLabel.LabelPrinter, idx: number) { + const highlight = this._activePrinter == idx ? "var(--bs-blue)" : "transparent"; + + // Generate a new label printer button for the given printer. + const element = document.createElement("div"); + element.innerHTML = ` +
  • +
    +
    + ${printer.printerOptions.serialNumber} +
    +
    + ${printer.printerOptions.labelWidthInches}" x ${printer.printerOptions.labelHeightInches}" +
    +
    + + +
  • `; + // And slap it into the button container. + this.btnContainer.appendChild(element); + + // Then wire up the button events so they work. + document.getElementById(`printto_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = this.addCanvasImageToLabelDoc(printer.getLabelDocument()); + await printer.sendDocument(doc); + }); + document.getElementById(`printer_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + if (this._activePrinter == printerIdx) { + // Don't refresh anything if we already have this printer selected.. + return; + } + this.activePrinterIndex = printerIdx; + this.redrawPrinterButtonHighlights(); + this.redrawTextCanvas(); + }); + document.getElementById(`printtest_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = WebLabel.ReadyToPrintDocuments.printTestLabelDocument( + printer.printerOptions.labelWidthDots); + await printer.sendDocument(doc); + }); + document.getElementById(`feedlabel_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = WebLabel.ReadyToPrintDocuments.feedLabelDocument; + await printer.sendDocument(doc); + }); + document.getElementById(`printconfig_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = WebLabel.ReadyToPrintDocuments.printConfigDocument; + await printer.sendDocument(doc); + }); + document.getElementById(`configprinter_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + this.showConfigModal(printer, printerIdx); + }); + } + + /** Redraw the text canvas size according to the printer. */ + private redrawTextCanvas() { + const printer = this.activePrinter; + if (printer == undefined) { + this.labelForm.classList.add('d-none'); + this.labelFormInstructions.classList.remove('d-none'); + return; + } else { + this.labelForm.classList.remove('d-none'); + this.labelFormInstructions.classList.add('d-none'); + } + + // Resize the canvas to match the label size. + const canvas = this.labelForm.querySelector("#labelCanvas") as HTMLCanvasElement; + // Add a small margin as printer alignment is not exact. + canvas.width = printer.printerOptions.labelWidthDots - 2; + canvas.height = printer.printerOptions.labelHeightDots - 2; + + const textarea = this.labelForm.querySelector('#labelFormText') as HTMLTextAreaElement; + textarea.value = "Enter your label text here!"; + this.renderTextForm(); + } + + /** Render the text form to the canvas */ + private renderTextForm() { + const printer = this.activePrinter; + if (printer == undefined) { + return; + } + + const textarea = this.labelForm.querySelector('#labelFormText') as HTMLTextAreaElement; + const fontsizer = this.labelForm.querySelector('#previewFontSize') as HTMLInputElement; + const canvas = this.labelForm.querySelector("#labelCanvas") as HTMLCanvasElement; + const pageContext = canvas.getContext('2d')!; + pageContext.clearRect(0, 0, canvas.width, canvas.height); + + const fontSize = Math.trunc(parseFloat(fontsizer.value)); + + // We'd like the preview image to be as close as possible to what the printer will + // actually print. To do this we don't draw text to the page's canvas directly, + // instead we draw to an offscreen canvas, render that canvas to a monochrome bitmap, + // then render *that* back to the page's canvas. This is a more accurate picture of + // what the label will end up looking like. + + // A more complex app could do this more gracefully! + const offscreenContext = new OffscreenCanvas(canvas.width, canvas.height).getContext('2d')!; + offscreenContext.font = `${fontSize}pt ${this.fontName}`; + offscreenContext.fillStyle = "#000000"; + + // fillText doesn't do newlines, do that manually + textarea.value.split('\n').forEach((l, i) => { + offscreenContext.fillText(l, 5, (i * fontSize + 2) + fontSize); + }) + + // Now into the monochrome bitmap. + const offscreenImg = offscreenContext.getImageData(0, 0, canvas.width, canvas.height); + const monoImg = WebLabel.BitmapGRF.fromCanvasImageData(offscreenImg, { trimWhitespace: false }); + // And finally back onto the page. + pageContext.putImageData(monoImg.toImageData(), 0, 0); + } + + /** Render the canvas to a document for printing */ + private addCanvasImageToLabelDoc(builder: WebLabel.ILabelDocumentBuilder): WebLabel.IDocument { + const canvas = this.labelForm.querySelector("#labelCanvas") as HTMLCanvasElement; + const imgData = canvas.getContext('2d')!.getImageData(0, 0, canvas.width, canvas.height); + + // One of the benefits of this library is being able to render images to a canvas element + // and sending that canvas directly to a label. This allows your webpage to generate complex + // images and fonts (like emoji!) that EPL/ZPL can't support. + return builder + .addImageFromImageData(imgData) + .addPrintCmd() + .finalize(); + } + + /** Send the contents of the config form as a config label to the printer. */ + private async updatePrinterConfig(e: SubmitEvent) { + e.preventDefault(); + + // Figure out the right printer + const formElement = this.configModal.querySelector('form')!; + const form = formElement.elements as HTMLFormControlsCollection; + const printerIdx = parseInt(formElement.querySelector('#modalPrinterIndexText')!.innerText); + const printer = this.printers[printerIdx]; + if (printer == undefined) { + return; + } + + form.modalSubmit.setAttribute("disabled", ""); + form.modalCancel.setAttribute("disabled", ""); + + // Pull the values out of the form. + const darkness = parseInt(form.modalDarkness.value) as DarknessPercent; + const rawSpeed = parseInt(form.modalSpeed.value) as PrintSpeed; + const labelWidthInches = parseFloat(form.modalLabelWidth.value); + const labelHeightInches = parseFloat(form.modalLabelHeight.value); + const autosense = form.modalWithAutosense.checked; + const offsetLeft = parseInt(form.modalLabelOffsetLeft.value); + const offsetTop = parseInt(form.modalLabelOffsetTop.value); + + // Construct the config document with the values from the form + const configDoc = printer.getConfigDocument(); + + // Form mode should be set first for other elements to work right. + switch (form.modalMediaType.value) { + case "continuous": + configDoc.setLabelMediaToContinuous(labelHeightInches); + break; + case "mark": + // TODO: Make a form for black line sensing. + configDoc.setLabelMediaToMarkSense(labelHeightInches, 16, 0); + break; + default: + case "gap": + // TODO: Make a form for label gap size. + configDoc.setLabelMediaToWebGapSense(labelHeightInches, 16); + break; + } + + configDoc + .setPrintDirection() + .setLabelPrintOriginOffsetCommand(offsetLeft, offsetTop) + .setPrintSpeed(rawSpeed) + .setDarknessConfig(darkness) + .setLabelDimensions(labelWidthInches); + const doc = autosense + ? configDoc.autosenseLabelLength() + : configDoc.finalize(); + // And send the whole shebang to the printer! + await printer.sendDocument(doc); + + form.modalSubmit.removeAttribute("disabled"); + form.modalCancel.removeAttribute("disabled"); + this.activePrinterIndex = printerIdx; + this.configModalHandle.hide(); + } +} + +const btnContainer = document.getElementById("printerlist")!; +const labelForm = document.getElementById("labelForm")!; +const labelFormInstructions = document.getElementById("labelFormInstructions")!; +const configModal = document.getElementById("printerOptionModal")!; + +const app = new BasicLabelDesignerApp(printerMgr, btnContainer, labelForm, labelFormInstructions, configModal); +await app.init();BasicLabelDesignerApp + + +// Make the TypeScript type system happy by adding a property to the Window object. +declare global { + interface Window { label_app: BasicLabelDesignerApp } +} +// Now we can access our printer in the dev console if we want to mess with it! +window.label_app = app; + + +await printerMgr.forceReconnect(); + +// We're done here. Bring in the dancing lobsters. \ No newline at end of file diff --git a/demo/test_index.ts b/demo/test_index.ts new file mode 100644 index 0000000..077cde3 --- /dev/null +++ b/demo/test_index.ts @@ -0,0 +1,437 @@ +import * as WebLabel from '../src/index.js'; +// This file exists to test the index.html's typescript. Unfortunately there isn't +// a good way to configure Visual Studio Code to, well, treat it as typescript. +//////////////////////////////////////////////////////////////////////////////// + +// First import the lib! +//import * as WebLabel from 'web-receiptline-printer'; + +// For this demo we're going to make use of the USB printer manager +// so it can take care of concerns like the USB connect and disconnect events. + +const printerMgr = new WebLabel.UsbDeviceManager( + window.navigator.usb, + WebLabel.LabelPrinter.fromUSBDevice, + { + // Enable debugging, so the dev console can fill up with interesting messages! + debug: true, + requestOptions: { + // Limit the USB devices we try to connect to. + filters: [ + { + vendorId: 0x0A5F // Zebra + } + ] + } + } +) + +// We'll wire up some basic event listeners to the printer manager. +// First, a button to prompt a user to add a printer. +const addPrinterBtn = document.getElementById('addprinter')!; +addPrinterBtn.addEventListener('click', async () => printerMgr.promptForNewDevice()); + +// Next a button to manually refresh all printers, just in case. +const refreshPrinterBtn = document.getElementById('refreshPrinters')!; +refreshPrinterBtn.addEventListener('click', async () => printerMgr.forceReconnect()); + +// Next we wire up some events on the PrinterUsbManager itself. +printerMgr.addEventListener('connectedDevice', ({ detail }) => { + const printer = detail.device; + console.log('New printer is a', printer.printerModel.model); + const config = printer.printerOptions; + console.log('Printer darkness is', config.darknessPercent, 'percent'); + console.log('Printer speed is', WebLabel.PrintSpeed[config.speed.printSpeed]); + console.log( + 'Label is', + config.labelWidthInches, + 'in wide and', + config.labelHeightInches, + 'in tall, with a gap of', + config.labelGapInches, + 'in.'); +}); +// There's also an event that will tell you when a printer disconnects. +printerMgr.addEventListener('disconnectedDevice', ({ detail }) => { + const printer = detail.device; + console.log('Lost printer', printer.printerModel.model, 'serial', printer.printerOptions.serialNumber); +}); + +// When the browser first loaded the page any previously connected printers would have caused +// a connection event. Our listener wasn't listening yet so missed it. +// It's good practice to force a reconnect once your event handlers are ready. +// We're going to skip this for now though, because we want it to happen after the app is ready. +//await printerMgr.reconnectAllPrinters(); + +// And that's all there is to setup! The page can now talk to printers. +// If you're using a chromebook this should just work. If you're on Windows +// you might need to do some driver setup, see the repo README for more details. + +// The rest of this demo is an example of a basic label generator app. + +// The app's logic is wrapped in a class just for ease of reading. +class BasicLabelDesignerApp { + constructor( + private manager: WebLabel.UsbDeviceManager, + private btnContainer: HTMLElement, + private labelForm: HTMLElement, + private labelFormInstructions: HTMLElement, + private configModal: HTMLElement + ) { + // Based on the containers, map the various listeners. + this.configModalHandle = new bootstrap.Modal(this.configModal); + this.configModal + .querySelector('form')! + .addEventListener('submit', this.updatePrinterConfig.bind(this)); + this.labelForm.addEventListener('blur', this.renderTextForm.bind(this)); + this.labelForm.addEventListener('keyup', this.renderTextForm.bind(this)); + + // Add a second set of event listeners for printer connect and disconnect to redraw + // the printer list when it changes. + this.manager.addEventListener('connectedDevice', () => { + this.activePrinterIndex = -1; + this.redrawPrinterButtons(); + }); + this.manager.addEventListener('disconnectedDevice', () => { + this.activePrinterIndex = -1; + this.redrawPrinterButtons(); + }); + + // Here's a nice font with a great set of emoji that work well for monochrome printing. + // The text font is fairly basic though, so we would like to use only the emoji out + // of this font and use a basic sans-serif font for regular text. + // https://fonts.google.com/noto/specimen/Noto+Emoji + const emojiFontName = 'noto-emoji'; + + // We can accomplish this with the unicodeRange property of our FontFace. We just + // need to list EVERY SINGLE EMOJI UNICODE RANGE to make it work. Fortunately someone + // has done this already: https://github.com/fraction/emoji-unicode-range + const emojiUnicodeRange = 'U+00A9,U+00AE,U+203C,U+2049,U+2122,U+2139,U+2194-2199,U+21A9-21AA,U+231A-231B,U+2328,U+23CF,U+23E9-23F3,U+23F8-23FA,U+24C2,U+25AA-25AB,U+25B6,U+25C0,U+25FB-25FE,U+2600-2604,U+260E,U+2611,U+2614-2615,U+2618,U+261D,U+2620,U+2622-2623,U+2626,U+262A,U+262E-262F,U+2638-263A,U+2640,U+2642,U+2648-2653,U+265F-2660,U+2663,U+2665-2666,U+2668,U+267B,U+267E-267F,U+2692-2697,U+2699,U+269B-269C,U+26A0-26A1,U+26AA-26AB,U+26B0-26B1,U+26BD-26BE,U+26C4-26C5,U+26C8,U+26CE,U+26CF,U+26D1,U+26D3-26D4,U+26E9-26EA,U+26F0-26F5,U+26F7-26FA,U+26FD,U+2702,U+2705,U+2708-2709,U+270A-270B,U+270C-270D,U+270F,U+2712,U+2714,U+2716,U+271D,U+2721,U+2728,U+2733-2734,U+2744,U+2747,U+274C,U+274E,U+2753-2755,U+2757,U+2763-2764,U+2795-2797,U+27A1,U+27B0,U+27BF,U+2934-2935,U+2B05-2B07,U+2B1B-2B1C,U+2B50,U+2B55,U+3030,U+303D,U+3297,U+3299,U+1F004,U+1F0CF,U+1F170-1F171,U+1F17E,U+1F17F,U+1F18E,U+1F191-1F19A,U+1F1E6-1F1FF,U+1F201-1F202,U+1F21A,U+1F22F,U+1F232-1F23A,U+1F250-1F251,U+1F300-1F320,U+1F321,U+1F324-1F32C,U+1F32D-1F32F,U+1F330-1F335,U+1F336,U+1F337-1F37C,U+1F37D,U+1F37E-1F37F,U+1F380-1F393,U+1F396-1F397,U+1F399-1F39B,U+1F39E-1F39F,U+1F3A0-1F3C4,U+1F3C5,U+1F3C6-1F3CA,U+1F3CB-1F3CE,U+1F3CF-1F3D3,U+1F3D4-1F3DF,U+1F3E0-1F3F0,U+1F3F3-1F3F5,U+1F3F7,U+1F3F8-1F3FF,U+1F400-1F43E,U+1F43F,U+1F440,U+1F441,U+1F442-1F4F7,U+1F4F8,U+1F4F9-1F4FC,U+1F4FD,U+1F4FF,U+1F500-1F53D,U+1F549-1F54A,U+1F54B-1F54E,U+1F550-1F567,U+1F56F-1F570,U+1F573-1F579,U+1F57A,U+1F587,U+1F58A-1F58D,U+1F590,U+1F595-1F596,U+1F5A4,U+1F5A5,U+1F5A8,U+1F5B1-1F5B2,U+1F5BC,U+1F5C2-1F5C4,U+1F5D1-1F5D3,U+1F5DC-1F5DE,U+1F5E1,U+1F5E3,U+1F5E8,U+1F5EF,U+1F5F3,U+1F5FA,U+1F5FB-1F5FF,U+1F600,U+1F601-1F610,U+1F611,U+1F612-1F614,U+1F615,U+1F616,U+1F617,U+1F618,U+1F619,U+1F61A,U+1F61B,U+1F61C-1F61E,U+1F61F,U+1F620-1F625,U+1F626-1F627,U+1F628-1F62B,U+1F62C,U+1F62D,U+1F62E-1F62F,U+1F630-1F633,U+1F634,U+1F635-1F640,U+1F641-1F642,U+1F643-1F644,U+1F645-1F64F,U+1F680-1F6C5,U+1F6CB-1F6CF,U+1F6D0,U+1F6D1-1F6D2,U+1F6D5,U+1F6E0-1F6E5,U+1F6E9,U+1F6EB-1F6EC,U+1F6F0,U+1F6F3,U+1F6F4-1F6F6,U+1F6F7-1F6F8,U+1F6F9,U+1F6FA,U+1F7E0-1F7EB,U+1F90D-1F90F,U+1F910-1F918,U+1F919-1F91E,U+1F91F,U+1F920-1F927,U+1F928-1F92F,U+1F930,U+1F931-1F932,U+1F933-1F93A,U+1F93C-1F93E,U+1F93F,U+1F940-1F945,U+1F947-1F94B,U+1F94C,U+1F94D-1F94F,U+1F950-1F95E,U+1F95F-1F96B,U+1F96C-1F970,U+1F971,U+1F973-1F976,U+1F97A,U+1F97B,U+1F97C-1F97F,U+1F980-1F984,U+1F985-1F991,U+1F992-1F997,U+1F998-1F9A2,U+1F9A5-1F9AA,U+1F9AE-1F9AF,U+1F9B0-1F9B9,U+1F9BA-1F9BF,U+1F9C0,U+1F9C1-1F9C2,U+1F9C3-1F9CA,U+1F9CD-1F9CF,U+1F9D0-1F9E6,U+1F9E7-1F9FF,U+1FA70-1FA73,U+1FA78-1FA7A,U+1FA80-1FA82,U+1FA90-1FA95,U+231A-231B,U+23E9-23EC,U+23F0,U+23F3,U+25FD-25FE,U+2614-2615,U+2648-2653,U+267F,U+2693,U+26A1,U+26AA-26AB,U+26BD-26BE,U+26C4-26C5,U+26CE,U+26D4,U+26EA,U+26F2-26F3,U+26F5,U+26FA,U+26FD,U+2705,U+270A-270B,U+2728,U+274C,U+274E,U+2753-2755,U+2757,U+2795-2797,U+27B0,U+27BF,U+2B1B-2B1C,U+2B50,U+2B55,U+1F004,U+1F0CF,U+1F18E,U+1F191-1F19A,U+1F1E6-1F1FF,U+1F201,U+1F21A,U+1F22F,U+1F232-1F236,U+1F238-1F23A,U+1F250-1F251,U+1F300-1F320,U+1F32D-1F32F,U+1F330-1F335,U+1F337-1F37C,U+1F37E-1F37F,U+1F380-1F393,U+1F3A0-1F3C4,U+1F3C5,U+1F3C6-1F3CA,U+1F3CF-1F3D3,U+1F3E0-1F3F0,U+1F3F4,U+1F3F8-1F3FF,U+1F400-1F43E,U+1F440,U+1F442-1F4F7,U+1F4F8,U+1F4F9-1F4FC,U+1F4FF,U+1F500-1F53D,U+1F54B-1F54E,U+1F550-1F567,U+1F57A,U+1F595-1F596,U+1F5A4,U+1F5FB-1F5FF,U+1F600,U+1F601-1F610,U+1F611,U+1F612-1F614,U+1F615,U+1F616,U+1F617,U+1F618,U+1F619,U+1F61A,U+1F61B,U+1F61C-1F61E,U+1F61F,U+1F620-1F625,U+1F626-1F627,U+1F628-1F62B,U+1F62C,U+1F62D,U+1F62E-1F62F,U+1F630-1F633,U+1F634,U+1F635-1F640,U+1F641-1F642,U+1F643-1F644,U+1F645-1F64F,U+1F680-1F6C5,U+1F6CC,U+1F6D0,U+1F6D1-1F6D2,U+1F6D5,U+1F6EB-1F6EC,U+1F6F4-1F6F6,U+1F6F7-1F6F8,U+1F6F9,U+1F6FA,U+1F7E0-1F7EB,U+1F90D-1F90F,U+1F910-1F918,U+1F919-1F91E,U+1F91F,U+1F920-1F927,U+1F928-1F92F,U+1F930,U+1F931-1F932,U+1F933-1F93A,U+1F93C-1F93E,U+1F93F,U+1F940-1F945,U+1F947-1F94B,U+1F94C,U+1F94D-1F94F,U+1F950-1F95E,U+1F95F-1F96B,U+1F96C-1F970,U+1F971,U+1F973-1F976,U+1F97A,U+1F97B,U+1F97C-1F97F,U+1F980-1F984,U+1F985-1F991,U+1F992-1F997,U+1F998-1F9A2,U+1F9A5-1F9AA,U+1F9AE-1F9AF,U+1F9B0-1F9B9,U+1F9BA-1F9BF,U+1F9C0,U+1F9C1-1F9C2,U+1F9C3-1F9CA,U+1F9CD-1F9CF,U+1F9D0-1F9E6,U+1F9E7-1F9FF,U+1FA70-1FA73,U+1FA78-1FA7A,U+1FA80-1FA82,U+1FA90-1FA95,U+1F3FB-1F3FF,U+261D,U+26F9,U+270A-270B,U+270C-270D,U+1F385,U+1F3C2-1F3C4,U+1F3C7,U+1F3CA,U+1F3CB-1F3CC,U+1F442-1F443,U+1F446-1F450,U+1F466-1F478,U+1F47C,U+1F481-1F483,U+1F485-1F487,U+1F48F,U+1F491,U+1F4AA,U+1F574-1F575,U+1F57A,U+1F590,U+1F595-1F596,U+1F645-1F647,U+1F64B-1F64F,U+1F6A3,U+1F6B4-1F6B6,U+1F6C0,U+1F6CC,U+1F90F,U+1F918,U+1F919-1F91E,U+1F91F,U+1F926,U+1F930,U+1F931-1F932,U+1F933-1F939,U+1F93C-1F93E,U+1F9B5-1F9B6,U+1F9B8-1F9B9,U+1F9BB,U+1F9CD-1F9CF,U+1F9D1-1F9DD,U+0023,U+002A,U+0030-0039,U+200D,U+20E3,U+FE0F,U+1F1E6-1F1FF,U+1F3FB-1F3FF,U+1F9B0-1F9B3,U+E0020-E007F,U+00A9,U+00AE,U+203C,U+2049,U+2122,U+2139,U+2194-2199,U+21A9-21AA,U+231A-231B,U+2328,U+2388,U+23CF,U+23E9-23F3,U+23F8-23FA,U+24C2,U+25AA-25AB,U+25B6,U+25C0,U+25FB-25FE,U+2600-2605,U+2607-2612,U+2614-2615,U+2616-2617,U+2618,U+2619,U+261A-266F,U+2670-2671,U+2672-267D,U+267E-267F,U+2680-2685,U+2690-2691,U+2692-269C,U+269D,U+269E-269F,U+26A0-26A1,U+26A2-26B1,U+26B2,U+26B3-26BC,U+26BD-26BF,U+26C0-26C3,U+26C4-26CD,U+26CE,U+26CF-26E1,U+26E2,U+26E3,U+26E4-26E7,U+26E8-26FF,U+2700,U+2701-2704,U+2705,U+2708-2709,U+270A-270B,U+270C-2712,U+2714,U+2716,U+271D,U+2721,U+2728,U+2733-2734,U+2744,U+2747,U+274C,U+274E,U+2753-2755,U+2757,U+2763-2767,U+2795-2797,U+27A1,U+27B0,U+27BF,U+2934-2935,U+2B05-2B07,U+2B1B-2B1C,U+2B50,U+2B55,U+3030,U+303D,U+3297,U+3299,U+1F000-1F02B,U+1F02C-1F02F,U+1F030-1F093,U+1F094-1F09F,U+1F0A0-1F0AE,U+1F0AF-1F0B0,U+1F0B1-1F0BE,U+1F0BF,U+1F0C0,U+1F0C1-1F0CF,U+1F0D0,U+1F0D1-1F0DF,U+1F0E0-1F0F5,U+1F0F6-1F0FF,U+1F10D-1F10F,U+1F12F,U+1F16C,U+1F16D-1F16F,U+1F170-1F171,U+1F17E,U+1F17F,U+1F18E,U+1F191-1F19A,U+1F1AD-1F1E5,U+1F201-1F202,U+1F203-1F20F,U+1F21A,U+1F22F,U+1F232-1F23A,U+1F23C-1F23F,U+1F249-1F24F,U+1F250-1F251,U+1F252-1F25F,U+1F260-1F265,U+1F266-1F2FF,U+1F300-1F320,U+1F321-1F32C,U+1F32D-1F32F,U+1F330-1F335,U+1F336,U+1F337-1F37C,U+1F37D,U+1F37E-1F37F,U+1F380-1F393,U+1F394-1F39F,U+1F3A0-1F3C4,U+1F3C5,U+1F3C6-1F3CA,U+1F3CB-1F3CE,U+1F3CF-1F3D3,U+1F3D4-1F3DF,U+1F3E0-1F3F0,U+1F3F1-1F3F7,U+1F3F8-1F3FA,U+1F400-1F43E,U+1F43F,U+1F440,U+1F441,U+1F442-1F4F7,U+1F4F8,U+1F4F9-1F4FC,U+1F4FD-1F4FE,U+1F4FF,U+1F500-1F53D,U+1F546-1F54A,U+1F54B-1F54F,U+1F550-1F567,U+1F568-1F579,U+1F57A,U+1F57B-1F5A3,U+1F5A4,U+1F5A5-1F5FA,U+1F5FB-1F5FF,U+1F600,U+1F601-1F610,U+1F611,U+1F612-1F614,U+1F615,U+1F616,U+1F617,U+1F618,U+1F619,U+1F61A,U+1F61B,U+1F61C-1F61E,U+1F61F,U+1F620-1F625,U+1F626-1F627,U+1F628-1F62B,U+1F62C,U+1F62D,U+1F62E-1F62F,U+1F630-1F633,U+1F634,U+1F635-1F640,U+1F641-1F642,U+1F643-1F644,U+1F645-1F64F,U+1F680-1F6C5,U+1F6C6-1F6CF,U+1F6D0,U+1F6D1-1F6D2,U+1F6D3-1F6D4,U+1F6D5,U+1F6D6-1F6DF,U+1F6E0-1F6EC,U+1F6ED-1F6EF,U+1F6F0-1F6F3,U+1F6F4-1F6F6,U+1F6F7-1F6F8,U+1F6F9,U+1F6FA,U+1F6FB-1F6FF,U+1F774-1F77F,U+1F7D5-1F7D8,U+1F7D9-1F7DF,U+1F7E0-1F7EB,U+1F7EC-1F7FF,U+1F80C-1F80F,U+1F848-1F84F,U+1F85A-1F85F,U+1F888-1F88F,U+1F8AE-1F8FF,U+1F90C,U+1F90D-1F90F,U+1F910-1F918,U+1F919-1F91E,U+1F91F,U+1F920-1F927,U+1F928-1F92F,U+1F930,U+1F931-1F932,U+1F933-1F93A,U+1F93C-1F93E,U+1F93F,U+1F940-1F945,U+1F947-1F94B,U+1F94C,U+1F94D-1F94F,U+1F950-1F95E,U+1F95F-1F96B,U+1F96C-1F970,U+1F971,U+1F972,U+1F973-1F976,U+1F977-1F979,U+1F97A,U+1F97B,U+1F97C-1F97F,U+1F980-1F984,U+1F985-1F991,U+1F992-1F997,U+1F998-1F9A2,U+1F9A3-1F9A4,U+1F9A5-1F9AA,U+1F9AB-1F9AD,U+1F9AE-1F9AF,U+1F9B0-1F9B9,U+1F9BA-1F9BF,U+1F9C0,U+1F9C1-1F9C2,U+1F9C3-1F9CA,U+1F9CB-1F9CC,U+1F9CD-1F9CF,U+1F9D0-1F9E6,U+1F9E7-1F9FF,U+1FA00-1FA53,U+1FA54-1FA5F,U+1FA60-1FA6D,U+1FA6E-1FA6F,U+1FA70-1FA73,U+1FA74-1FA77,U+1FA78-1FA7A,U+1FA7B-1FA7F,U+1FA80-1FA82,U+1FA83-1FA8F,U+1FA90-1FA95,U+1FA96-1FFFD'; + + // And then we can use that range with our font when we load it. + const emojiOnlyFont = new FontFace(emojiFontName, 'url(fonts/NotoEmoji-Regular.ttf)', { + unicodeRange: emojiUnicodeRange, + }); + emojiOnlyFont.load().then(() => { + document.fonts.add(emojiOnlyFont); + }); + // We then set our fallback font as part of the font family we use in the canvas. + // This order matters, latter fonts will use the unicodeRange to override earlier fonts. + this.fontName = `Sans-serif, ${emojiFontName}` + } + + // Some storage fields and utility properties + private fontName: string; + private configModalHandle: any; + + get printers(): readonly WebLabel.LabelPrinter[] { + return this.manager.devices; + } + + // Track which printer is currently selected for operations + private _activePrinter = 0; + get activePrinter(): WebLabel.LabelPrinter | undefined { + return this._activePrinter < 0 || this._activePrinter > this.printers.length + ? undefined + : this.printers[this._activePrinter]; + } + set activePrinterIndex(printerIdx: number) { + this._activePrinter = printerIdx; + this.redrawTextCanvas(); + } + + /** Initialize the app */ + public async init() { + this.redrawPrinterButtons(); + this.redrawTextCanvas(); + } + + /** Display the configuration for a printer. */ + public showConfigModal(printer: WebLabel.LabelPrinter, printerIdx: number) { + if (printer === undefined) { + return; + } + const config = printer.printerOptions; + + // Translate the available speeds to options to be selected + const speedSelect = this.configModal.querySelector('#modalSpeed')!; + speedSelect.innerHTML = ''; + const speedTable = printer.printerModel.speedTable as ReadonlyMap; + for (const [key, val] of speedTable) { + // Skip utility values, so long as there's more than the defaults. + // Mobile printers *only* support auto, for example. + if ((speedTable.size > 3) + && (key === WebLabel.PrintSpeed.ipsAuto + || key === WebLabel.PrintSpeed.ipsPrinterMax + || key === WebLabel.PrintSpeed.ipsPrinterMin + )) { + continue; + } + const opt = document.createElement('option'); + opt.value = key; + opt.innerHTML = WebLabel.PrintSpeed[key].substring(3).replaceAll('_', '.') + ' ips'; + speedSelect.appendChild(opt); + } + speedSelect.value = config.speed.printSpeed; + + this.configModal.querySelector('#modalPrinterIndex')!.value = config.serialNumber; + this.configModal.querySelector('#modalPrinterIndexText')!.textContent = printerIdx; + this.configModal.querySelector('#modalLabelWidth')!.value = config.labelWidthInches; + this.configModal.querySelector('#modalLabelHeight')!.value = config.labelHeightInches; + this.configModal.querySelector('#modalDarkness')!.value = config.darknessPercent; + this.configModalHandle.show(); + } + + /** Erase and re-draw the list of printer buttons in the UI. */ + private redrawPrinterButtons() { + this.btnContainer.innerHTML = ''; + this.printers.forEach((printer, idx) => this.drawPrinterButton(printer, idx)); + } + + /** Highlight only the currently selected printer. */ + private redrawPrinterButtonHighlights() { + this.printers.forEach((printer, idx) => { + const highlight = this._activePrinter === idx ? "var(--bs-blue)" : "transparent"; + const element = document.getElementById(`printer_${idx}`)!; + element.style.background = `linear-gradient(to right, ${highlight}, ${highlight}, grey, grey)`; + }); + } + + /** Add a printer's button UI to the list of printers. */ + private drawPrinterButton(printer: WebLabel.LabelPrinter, idx: number) { + const highlight = this._activePrinter === idx ? "var(--bs-blue)" : "transparent"; + + // Generate a new label printer button for the given printer. + const element = document.createElement("div"); + element.innerHTML = ` +
  • +
    +
    + ${printer.printerOptions.serialNumber} +
    +
    + ${printer.printerOptions.labelWidthInches}" x ${printer.printerOptions.labelHeightInches}" +
    +
    + + +
  • `; + // And slap it into the button container. + this.btnContainer.appendChild(element); + + // Then wire up the button events so they work. + document.getElementById(`printto_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = this.addCanvasImageToLabelDoc(printer.getLabelDocument()); + await printer.sendDocument(doc); + }); + document.getElementById(`printer_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + if (this._activePrinter === printerIdx) { + // Don't refresh anything if we already have this printer selected.. + return; + } + this.activePrinterIndex = printerIdx; + this.redrawPrinterButtonHighlights(); + this.redrawTextCanvas(); + }); + document.getElementById(`printtest_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = WebLabel.ReadyToPrintDocuments.printTestLabelDocument( + printer.printerOptions.labelWidthDots); + await printer.sendDocument(doc); + }); + document.getElementById(`feedlabel_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = WebLabel.ReadyToPrintDocuments.feedLabelDocument; + await printer.sendDocument(doc); + }); + document.getElementById(`printconfig_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + const doc = WebLabel.ReadyToPrintDocuments.printConfigDocument; + await printer.sendDocument(doc); + }); + document.getElementById(`configprinter_${idx}`)! + .addEventListener('click', async (e) => { + e.preventDefault(); + const printerIdx = (e.currentTarget as HTMLAnchorElement).dataset.printerIdx as unknown as number; + const printer = this.printers[printerIdx]; + this.showConfigModal(printer, printerIdx); + }); + } + + /** Redraw the text canvas size according to the printer. */ + private redrawTextCanvas() { + const printer = this.activePrinter; + if (printer === undefined) { + this.labelForm.classList.add('d-none'); + this.labelFormInstructions.classList.remove('d-none'); + return; + } else { + this.labelForm.classList.remove('d-none'); + this.labelFormInstructions.classList.add('d-none'); + } + + // Resize the canvas to match the label size. + const canvas = this.labelForm.querySelector("#labelCanvas") as HTMLCanvasElement; + // Add a small margin as printer alignment is not exact. + canvas.width = printer.printerOptions.labelWidthDots - 2; + canvas.height = printer.printerOptions.labelHeightDots - 2; + + const textarea = this.labelForm.querySelector('#labelFormText') as HTMLTextAreaElement; + textarea.value = "Enter your label text here!"; + this.renderTextForm(); + } + + /** Render the text form to the canvas */ + private renderTextForm() { + const printer = this.activePrinter; + if (printer === undefined) { + return; + } + + const textarea = this.labelForm.querySelector('#labelFormText') as HTMLTextAreaElement; + const canvas = this.labelForm.querySelector("#labelCanvas") as HTMLCanvasElement; + const pageContext = canvas.getContext('2d'); + pageContext!.clearRect(0, 0, canvas.width, canvas.height); + + // We'd like the preview image to be as close as possible to what the printer will + // actually print. To do this we don't draw text to the page's canvas directly, + // instead we draw to an offscreen canvas, render that canvas to a monochrome bitmap, + // then render *that* back to the page's canvas. This is a more accurate picture of + // what the label will end up looking like. + + // A more complex app could do this more gracefully! + const offscreenContext = new OffscreenCanvas(canvas.width, canvas.height).getContext('2d'); + offscreenContext!.font = `30pt ${this.fontName}`; + offscreenContext!.fillStyle = "#000000"; + + // fillText doesn't do newlines, do that manually + textarea.value.split('\n').forEach((l, i) => { + offscreenContext!.fillText(l, 5, (i * 31) + 30); + }) + + // Now into the monochrome bitmap. + const offscreenImg = offscreenContext!.getImageData(0, 0, canvas.width, canvas.height); + const monoImg = WebLabel.BitmapGRF.fromCanvasImageData(offscreenImg, { trimWhitespace: false }); + // And finally back onto the page. + pageContext!.putImageData(monoImg.toImageData(), 0, 0); + } + + /** Render the canvas to a document for printing */ + private addCanvasImageToLabelDoc(builder: WebLabel.ILabelDocumentBuilder): WebLabel.IDocument { + const canvas = this.labelForm.querySelector("#labelCanvas") as HTMLCanvasElement; + const imgData = canvas.getContext('2d')!.getImageData(0, 0, canvas.width, canvas.height); + + // One of the benefits of this library is being able to render images to a canvas element + // and sending that canvas directly to a label. This allows your webpage to generate complex + // images and fonts (like emoji!) that EPL/ZPL can't support. + return builder + .addImageFromImageData(imgData) + .addPrintCmd() + .finalize(); + } + + /** Send the contents of the config form as a config label to the printer. */ + private async updatePrinterConfig(e: SubmitEvent) { + e.preventDefault(); + + // Figure out the right printer + const formElement = this.configModal.querySelector('form')!; + const form = formElement.elements as HTMLFormControlsCollection; + const printerIdx = parseInt((formElement.querySelector('#modalPrinterIndexText') as HTMLFormElement).innerText); + const printer = this.printers[printerIdx]; + if (printer === undefined) { + return; + } + + form.modalSubmit.setAttribute("disabled", ""); + form.modalCancel.setAttribute("disabled", ""); + + // Pull the values out of the form. + const darkness = parseInt(form.modalDarkness.value) as DarknessPercent; + const rawSpeed = parseInt(form.modalSpeed.value) as PrintSpeed; + const labelWidthInches = parseFloat(form.modalLabelWidth.value); + const autosense = form.modalWithAutosense.checked; + + // Construct the config document with the values from the form + const configDoc = printer + .getConfigDocument() + .setPrintDirection() + .setLabelHomeOffsetDots(0, 0) + .setPrintSpeed(rawSpeed) + .setDarknessConfig(darkness) + .setLabelDimensions(labelWidthInches); + const doc = autosense + ? configDoc.autosenseLabelLength() + : configDoc.finalize(); + // And send the whole shebang to the printer! + await printer.sendDocument(doc); + + form.modalSubmit.removeAttribute("disabled"); + form.modalCancel.removeAttribute("disabled"); + this.activePrinterIndex = printerIdx; + this.configModalHandle.hide(); + } +} + +// With the app class defined we can run it. +// First up collect the basic structure of the app +const btnContainer = document.getElementById("printerlist")!; +const labelForm = document.getElementById("labelForm")!; +const labelFormInstructions = document.getElementById("labelFormInstructions")!; +const configModal = document.getElementById("printerOptionModal")!; + +// And feed that into the app class to manage the elements +const app = new BasicLabelDesignerApp(printerMgr, btnContainer, labelForm, labelFormInstructions, configModal); +// and let it take over the UI. +await app.init(); + +// Make the TypeScript type system happy by adding a property to the Window object. +declare global { + interface Window { printer_app: BasicLabelDesignerApp } +} +// Now we can access our printer in the dev console if we want to mess with it! +window.printer_app = app; + +// Now we'll fire the reconnect since our UI is wired up. +await printerMgr.forceReconnect(); + +// We're done here. Bring in the dancing lobsters. \ No newline at end of file diff --git a/demo/ts-browser.js b/demo/ts-browser.js index 8f0f232..1b4edd0 100644 --- a/demo/ts-browser.js +++ b/demo/ts-browser.js @@ -17,7 +17,7 @@ window.addEventListener('DOMContentLoaded', async () => { const scripts = document.getElementsByTagName('script'); // Register the Service Worker which will polyfill the HTML module behavior. - await navigator.serviceWorker.register('../demo-sw.js'); + await navigator.serviceWorker.register('./demo-sw.js'); // Unfortunately, we have to wait for the Service Worker to ready before // actually loading the application so that it can intercept the HTML requests. diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index 25c9dc2..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { Config } from 'jest'; - -export default async (): Promise => { - return { - preset: 'ts-jest', - extensionsToTreatAsEsm: ['.ts', '.tsx'], - transform: { - '^.+\\.(t|j)sx?$': '@swc/jest' - }, - moduleNameMapper: { - '^(\\.{1,2}/.*)\\.js$': '$1' - }, - testEnvironment: 'node', - testPathIgnorePatterns: ['/node_modules/', '/dist/'], - collectCoverage: true, - verbose: true - }; -}; diff --git a/package-lock.json b/package-lock.json index c166d13..809f9a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,675 +1,502 @@ { "name": "webzlp", - "version": "1.0.1", + "version": "2.0.0-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "webzlp", - "version": "1.0.1", + "version": "2.0.0-alpha.1", "license": "GPL-3.0-only", "devDependencies": { - "@swc/core": "^1.3.24", - "@swc/jest": "^0.2.24", - "@types/jest": "^29.2.0", - "@types/w3c-web-usb": "^1.0.6", - "@typescript-eslint/eslint-plugin": "^5.41.0", - "@typescript-eslint/parser": "^5.41.0", - "eslint": "^8.26.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.2.1", + "@types/node": "^20.8.9", + "@types/w3c-web-usb": "^1.0.10", + "@typescript-eslint/eslint-plugin": "^6.17.0", + "@typescript-eslint/parser": "^6.17.0", + "@vitest/coverage-v8": "^1.1.3", + "eslint": "^8.56.0", "https-localhost": "^4.7.1", - "jest": "^29.2.2", - "jest-canvas-mock": "^2.4.0", - "prettier": "^2.7.1", - "ts-jest": "^29.0.3", - "ts-node": "^10.9.1", - "typescript": "^4.9.4" + "typescript": "^5.2.2", + "vite": "5.0.11", + "vite-plugin-dts": "3.7.0", + "vite-plugin-eslint": "^1.8.1", + "vitest": "1.1.3" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", + "cpu": [ + "ppc64" + ], "dev": true, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "node_modules/@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "node_modules/@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "node_modules/@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "node_modules/@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", + "cpu": [ + "arm" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", + "cpu": [ + "ia32" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", + "cpu": [ + "loong64" + ], "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", + "cpu": [ + "mips64el" + ], "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "color-name": "1.1.3" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.8.0" + "node": ">=12" } }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", + "cpu": [ + "x64" + ], "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=12" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=12" } }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "node_modules/@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -683,13 +510,22 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -711,573 +547,232 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/@microsoft/api-extractor": { + "version": "7.39.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.39.0.tgz", + "integrity": "sha512-PuXxzadgnvp+wdeZFPonssRAj/EW4Gm4s75TXzPk09h3wJ8RS3x7typf95B4vwZRrPTQBGopdUl+/vHvlPdAcg==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "@microsoft/api-extractor-model": "7.28.3", + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "3.62.0", + "@rushstack/rig-package": "0.5.1", + "@rushstack/ts-command-line": "4.17.1", + "colors": "~1.2.1", + "lodash": "~4.17.15", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.3.3" }, - "engines": { - "node": ">=8" + "bin": { + "api-extractor": "bin/api-extractor" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@microsoft/api-extractor-model": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.3.tgz", + "integrity": "sha512-wT/kB2oDbdZXITyDh2SQLzaWwTOFbV326fP0pUwNW00WeliARs0qjmXBWmGWardEzp2U3/axkO3Lboqun6vrig==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "3.62.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true }, - "node_modules/@jest/console": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz", - "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==", + "node_modules/@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" } }, - "node_modules/@jest/core": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz", - "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==", + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "dependencies": { - "@jest/console": "^29.3.1", - "@jest/reporters": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-resolve-dependencies": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "jest-watcher": "^29.3.1", - "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jest/create-cache-key-function": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz", - "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 8" } }, - "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 8" } }, - "node_modules/@jest/create-cache-key-function/node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jest/environment": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", - "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "jest-mock": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==", - "dev": true, - "dependencies": { - "expect": "^29.3.1", - "jest-snapshot": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", - "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.2.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", - "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", - "dev": true, - "dependencies": { - "@jest/types": "^29.3.1", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz", - "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/types": "^29.3.1", - "jest-mock": "^29.3.1" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 8" } }, - "node_modules/@jest/reporters": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz", - "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==", + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { - "node-notifier": { + "rollup": { "optional": true } } }, - "node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz", - "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==", - "dev": true, - "dependencies": { - "@jest/console": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz", - "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.3.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz", - "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.3.1", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", - "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.4.tgz", + "integrity": "sha512-ub/SN3yWqIv5CWiAZPHVS1DloyZsJbtXmX4HxUTIpS0BHm9pW5iYBo2mIZi+hE3AeiTzHz33blwSnhdUo+9NpA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.4.tgz", + "integrity": "sha512-ehcBrOR5XTl0W0t2WxfTyHCR/3Cq2jfb+I4W+Ch8Y9b5G+vbAecVv0Fx/J1QKktOrgUYsIKxWAKgIpvw56IFNA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@swc/core": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.24.tgz", - "integrity": "sha512-QMOTd0AgiUT3K1crxLRqd3gw0f3FC8hhH1vvlIlryvYqU4c+FJ/T2G4ZhMKLxQlZ/jX6Rhk0gKINZRBxy2GFyQ==", - "dev": true, - "hasInstallScript": true, - "bin": { - "swcx": "run_swcx.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.24", - "@swc/core-darwin-x64": "1.3.24", - "@swc/core-linux-arm-gnueabihf": "1.3.24", - "@swc/core-linux-arm64-gnu": "1.3.24", - "@swc/core-linux-arm64-musl": "1.3.24", - "@swc/core-linux-x64-gnu": "1.3.24", - "@swc/core-linux-x64-musl": "1.3.24", - "@swc/core-win32-arm64-msvc": "1.3.24", - "@swc/core-win32-ia32-msvc": "1.3.24", - "@swc/core-win32-x64-msvc": "1.3.24" - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.24.tgz", - "integrity": "sha512-rR+9UpWm+fGXcipsjCst2hIL1GYIbo0YTLhJZWdIpQD6KRHHJMFXiydMgQQkDj2Ml7HpqUVgxj6m4ZWYL8b0OA==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.4.tgz", + "integrity": "sha512-1fzh1lWExwSTWy8vJPnNbNM02WZDS8AW3McEOb7wW+nPChLKf3WG2aG7fhaUmfX5FKw9zhsF5+MBwArGyNM7NA==", "cpu": [ "arm64" ], @@ -1285,15 +780,12 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.24.tgz", - "integrity": "sha512-px+5vkGtgPH0m3FkkTBHynlRdS5rRz+lK+wiXIuBZFJSySWFl6RkKbvwkD+sf0MpazQlqwlv/rTOGJBw6oDffg==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.4.tgz", + "integrity": "sha512-Gc6cukkF38RcYQ6uPdiXi70JB0f29CwcQ7+r4QpfNpQFVHXRd0DfWFidoGxjSx1DwOETM97JPz1RXL5ISSB0pA==", "cpu": [ "x64" ], @@ -1301,15 +793,12 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.24.tgz", - "integrity": "sha512-jLs8ZOdTV4UW4J12E143QJ4mOMONQtqgAnuhBbRuWFzQ3ny1dfoC3P1jNWAJ2Xi59XdxAIXn0PggPNH4Kh34kw==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.4.tgz", + "integrity": "sha512-g21RTeFzoTl8GxosHbnQZ0/JkuFIB13C3T7Y0HtKzOXmoHhewLbVTFBQZu+z5m9STH6FZ7L/oPgU4Nm5ErN2fw==", "cpu": [ "arm" ], @@ -1317,15 +806,12 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.24.tgz", - "integrity": "sha512-A/v0h70BekrwGpp1DlzIFGcHQ3QQ2PexXcnnuIBZeMc9gNmHlcZmg3EcwAnaUDiokhNuSUFA/wV94yk1OqmSkw==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.4.tgz", + "integrity": "sha512-TVYVWD/SYwWzGGnbfTkrNpdE4HON46orgMNHCivlXmlsSGQOx/OHHYiQcMIOx38/GWgwr/po2LBn7wypkWw/Mg==", "cpu": [ "arm64" ], @@ -1333,15 +819,12 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.24.tgz", - "integrity": "sha512-pbc9eArWPTiMrbpS/pJo0IiQNAKAQBcBIDjWBGP1tcw2iDXYLw4bruwz9kI/VjakbshWb8MoE4T5ClkeuULvSw==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.4.tgz", + "integrity": "sha512-XcKvuendwizYYhFxpvQ3xVpzje2HHImzg33wL9zvxtj77HvPStbSGI9czrdbfrf8DGMcNNReH9pVZv8qejAQ5A==", "cpu": [ "arm64" ], @@ -1349,15 +832,25 @@ "optional": true, "os": [ "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.4.tgz", + "integrity": "sha512-LFHS/8Q+I9YA0yVETyjonMJ3UA+DczeBd/MqNEzsGSTdNvSJa1OJZcSH8GiXLvcizgp9AlHs2walqRcqzjOi3A==", + "cpu": [ + "riscv64" ], - "engines": { - "node": ">=10" - } + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.24.tgz", - "integrity": "sha512-pP5pOLlY1xd352qo7rTlpVPUI9/9VhOd4b3Lk+LzfZDq9bTL2NDlGfyrPiwa5DGHMSzrugH56K2J68eutkxYVA==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.4.tgz", + "integrity": "sha512-dIYgo+j1+yfy81i0YVU5KnQrIJZE8ERomx17ReU4GREjGtDW4X+nvkBak2xAUpyqLs4eleDSj3RrV72fQos7zw==", "cpu": [ "x64" ], @@ -1365,15 +858,12 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.24.tgz", - "integrity": "sha512-phNbP7zGp+Wcyxq1Qxlpe5KkxO7WLT2kVQUC7aDFGlVdCr+xdXsfH1MzheHtnr0kqTVQX1aiM8XXXHfFxR0oNA==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.4.tgz", + "integrity": "sha512-RoaYxjdHQ5TPjaPrLsfKqR3pakMr3JGqZ+jZM0zP2IkDtsGa4CqYaWSfQmZVgFUCgLrTnzX+cnHS3nfl+kB6ZQ==", "cpu": [ "x64" ], @@ -1381,15 +871,12 @@ "optional": true, "os": [ "linux" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.24.tgz", - "integrity": "sha512-qhbiJTWAOqyR+K9xnGmCkOWSz2EmWpDBstEJCEOTc6FZiEdbiTscDmqTcMbCKaTHGu8t+6erVA4t65/Eg6uWPA==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.4.tgz", + "integrity": "sha512-T8Q3XHV+Jjf5e49B4EAaLKV74BbX7/qYBRQ8Wop/+TyyU0k+vSjiLVSHNWdVd1goMjZcbhDmYZUYW5RFqkBNHQ==", "cpu": [ "arm64" ], @@ -1397,15 +884,12 @@ "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.24.tgz", - "integrity": "sha512-JfghIlscE4Rz+Lc08lSoDh+R0cWxrISed5biogFfE6vZqhaDnw3E5Qshqw7O3pIaiq8L2u1nmzuyP581ZmpbRA==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.4.tgz", + "integrity": "sha512-z+JQ7JirDUHAsMecVydnBPWLwJjbppU+7LZjffGf+Jvrxq+dVjIE7By163Sc9DKc3ADSU50qPVw0KonBS+a+HQ==", "cpu": [ "ia32" ], @@ -1413,15 +897,12 @@ "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.24.tgz", - "integrity": "sha512-3AmJRr0hwciwDBbzUNqaftvppzS8v9X/iv/Wl7YaVLBVpPfQvaZzfqLycvNMGLZb5vIKXR/u58txg3dRBGsJtw==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.4.tgz", + "integrity": "sha512-LfdGXCV9rdEify1oxlN9eamvDSjv9md9ZVMAbNHA87xqIfFCxImxan9qZ8+Un54iK2nnqPlbnSi4R54ONtbWBw==", "cpu": [ "x64" ], @@ -1429,211 +910,151 @@ "optional": true, "os": [ "win32" - ], - "engines": { - "node": ">=10" - } + ] }, - "node_modules/@swc/jest": { - "version": "0.2.24", - "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.24.tgz", - "integrity": "sha512-fwgxQbM1wXzyKzl1+IW0aGrRvAA8k0Y3NxFhKigbPjOJ4mCKnWEcNX9HQS3gshflcxq8YKhadabGUVfdwjCr6Q==", + "node_modules/@rushstack/node-core-library": { + "version": "3.62.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz", + "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==", "dev": true, "dependencies": { - "@jest/create-cache-key-function": "^27.4.2", - "jsonc-parser": "^3.2.0" - }, - "engines": { - "npm": ">= 7.0.0" + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" }, "peerDependencies": { - "@swc/core": "*" + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "node_modules/@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "node_modules/@rushstack/rig-package": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", + "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "node_modules/@rushstack/ts-command-line": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz", + "integrity": "sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "node_modules/@rushstack/ts-command-line/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.1.tgz", + "integrity": "sha512-18PLWRzhy9glDQp3+wOgfLYRWlhgX0azxgJ63rdpoUHyrC9z0f5CkFburjQx4uD7ZCruw85ZtMt6K+L+R8fLJQ==", "dev": true, "dependencies": { - "@types/node": "*" + "@types/estree": "*", + "@types/json-schema": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.2.tgz", - "integrity": "sha512-og1wAmdxKoS71K2ZwSVqWPX6OVn3ihZ6ZT2qvZvZQm90lJVDyXIjYcu4Khx2CNIeaFv12rOU/YObOsI3VOkzog==", - "dev": true, - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true + "version": "20.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.7.tgz", + "integrity": "sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, "node_modules/@types/w3c-web-usb": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.6.tgz", - "integrity": "sha512-cSjhgrr8g4KbPnnijAr/KJDNKa/bBa+ixYkywFRvrhvi9n1WEl7yYbtRyzE6jqNQiSxxJxoAW3STaOQwJHndaw==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz", + "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.41.0.tgz", - "integrity": "sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.0.tgz", + "integrity": "sha512-3lqEvQUdCozi6d1mddWqd+kf8KxmGq2Plzx36BlkjuQe3rSTm/O98cLf0A4uDO+a5N1KD2SeEEl6fW97YHY+6w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/type-utils": "5.41.0", - "@typescript-eslint/utils": "5.41.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.18.0", + "@typescript-eslint/type-utils": "6.18.0", + "@typescript-eslint/utils": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0", "debug": "^4.3.4", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1642,25 +1063,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.41.0.tgz", - "integrity": "sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.0.tgz", + "integrity": "sha512-v6uR68SFvqhNQT41frCMCQpsP+5vySy6IdgjlzUWoo7ALCnpaWYcz/Ij2k4L8cEsL0wkvOviCMpjmtRtHNOKzA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", + "@typescript-eslint/scope-manager": "6.18.0", + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/typescript-estree": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1669,16 +1091,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.41.0.tgz", - "integrity": "sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.0.tgz", + "integrity": "sha512-o/UoDT2NgOJ2VfHpfr+KBY2ErWvCySNUIX/X7O9g8Zzt/tXdpfEU43qbNk8LVuWUT2E0ptzTWXh79i74PP0twA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0" + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1686,25 +1108,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.41.0.tgz", - "integrity": "sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.0.tgz", + "integrity": "sha512-ZeMtrXnGmTcHciJN1+u2CigWEEXgy1ufoxtWcHORt5kGvpjjIlK9MUhzHm4RM8iVy6dqSaZA/6PVkX6+r+ChjQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.41.0", - "@typescript-eslint/utils": "5.41.0", + "@typescript-eslint/typescript-estree": "6.18.0", + "@typescript-eslint/utils": "6.18.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1713,12 +1135,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.41.0.tgz", - "integrity": "sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.0.tgz", + "integrity": "sha512-/RFVIccwkwSdW/1zeMx3hADShWbgBxBnV/qSrex6607isYjj05t36P6LyONgqdUrNLl5TYU8NIKdHUYpFvExkA==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1726,21 +1148,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz", - "integrity": "sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.0.tgz", + "integrity": "sha512-klNvl+Ql4NsBNGB4W9TZ2Od03lm7aGvTbs0wYaFYsplVPhr+oeXjlPZCDI4U9jgJIDK38W1FKhacCFzCC+nbIg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0", + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1752,49 +1175,316 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.41.0.tgz", - "integrity": "sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.0.tgz", + "integrity": "sha512-wiKKCbUeDPGaYEYQh1S580dGxJ/V9HI7K5sbGAVklyf+o5g3O+adnS4UNJajplF4e7z2q0uVBaTdT/yLb4XAVA==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.18.0", + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/typescript-estree": "6.18.0", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.41.0.tgz", - "integrity": "sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.0.tgz", + "integrity": "sha512-1wetAlSZpewRDb2h9p/Q8kRjdGuqdTAQbkJIOUMLug2LBLG+QOjiWoSj6/3B/hA9/tVTFFdtiKvAYoYnSRW/RA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.41.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.18.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vitest/coverage-v8": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.1.3.tgz", + "integrity": "sha512-Uput7t3eIcbSTOTQBzGtS+0kah96bX+szW9qQrLeGe3UmgL2Akn8POnyC2lH7XsnREZOds9aCUTxgXf+4HX5RA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.2", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "^1.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.1.3.tgz", + "integrity": "sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.1.3", + "@vitest/utils": "1.1.3", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.1.3.tgz", + "integrity": "sha512-Va2XbWMnhSdDEh/OFxyUltgQuuDRxnarK1hW5QNN4URpQrqq6jtt8cfww/pQQ4i0LjoYxh/3bYWvDFlR9tU73g==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.1.3", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.1.3.tgz", + "integrity": "sha512-U0r8pRXsLAdxSVAyGNcqOU2H3Z4Y2dAAGGelL50O0QRMdi1WWeYHdrH/QWpN1e8juWfVKsb8B+pyJwTC+4Gy9w==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.1.3.tgz", + "integrity": "sha512-Ec0qWyGS5LhATFQtldvChPTAHv08yHIOZfiNcjwRQbFPHpkih0md9KAbs7TfeIfL7OFKoe7B/6ukBTqByubXkQ==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.1.3.tgz", + "integrity": "sha512-Dyt3UMcdElTll2H75vhxfpZu03uFpXRCHxWnzcrFjZxT1kTbq8ALUYIeBgGolo1gldVdI0YSlQRacsqxTwNqwg==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "dev": true, + "dependencies": { + "@volar/source-map": "1.11.1" + } + }, + "node_modules/@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", + "dev": true, + "dependencies": { + "muggle-string": "^0.3.1" + } + }, + "node_modules/@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", + "dev": true, + "dependencies": { + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.5.tgz", + "integrity": "sha512-Daka7P1z2AgKjzuueWXhwzIsKu0NkLB6vGbNVEV2iJ8GJTrzraZo/Sk4GWCMRtd/qVi3zwnk+Owbd/xSZbwHtQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.6", + "@vue/shared": "3.4.5", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.5.tgz", + "integrity": "sha512-J8YlxknJVd90SXFJ4HwGANSAXsx5I0lK30sO/zvYV7s5gXf7gZR7r/1BmZ2ju7RGH1lnc6bpBc6nL61yW+PsAQ==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.4.5", + "@vue/shared": "3.4.5" + } + }, + "node_modules/@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", + "dev": true, + "dependencies": { + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.5.tgz", + "integrity": "sha512-6XptuzlMvN4l4cDnDw36pdGEV+9njYkQ1ZE0Q6iZLwrKefKaOJyiFmcP3/KBDHbt72cJZGtllAc1GaHe6XGAyg==", + "dev": true + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1809,9 +1499,9 @@ } }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1830,9 +1520,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", "dev": true, "engines": { "node": ">=0.4.0" @@ -1854,33 +1544,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1905,31 +1568,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/appdata-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/appdata-path/-/appdata-path-1.0.0.tgz", "integrity": "sha512-ZbH3ezXfnT/YE3NdqduIt4lBV+H0ybvA2Qx3K76gIjQvh8gROpDFdDLpx6B1QJtW7zxisCbpTlCLhKqoR8cDBw==", "dev": true }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1951,95 +1595,13 @@ "node": ">=8" } }, - "node_modules/babel-jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", - "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==", + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, - "dependencies": { - "@jest/transform": "^29.3.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.2.0", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "*" } }, "node_modules/balanced-match": { @@ -2118,61 +1680,6 @@ "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -2182,6 +1689,15 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2204,31 +1720,24 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/chai": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.0.tgz", + "integrity": "sha512-x9cHNq1uvkCdU+5xTkNh5WtgD4e4yDFCsp9jVc7N7qVeKeftv3gO/ZrviX5d+3ZfxdYnZXZYujjRInu1RogU6A==", "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2245,60 +1754,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.6.1.tgz", - "integrity": "sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "get-func-name": "^2.0.2" }, "engines": { - "node": ">=12" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": "*" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2317,6 +1784,25 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -2362,6 +1848,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2449,12 +1941,6 @@ "node": ">= 0.10" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2469,10 +1955,10 @@ "node": ">= 8" } }, - "node_modules/cssfontparser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", - "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", "dev": true }, "node_modules/debug": { @@ -2492,11 +1978,17 @@ } } }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } }, "node_modules/deep-is": { "version": "0.1.4", @@ -2504,15 +1996,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2532,34 +2015,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", - "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -2595,30 +2060,6 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -2628,22 +2069,54 @@ "node": ">= 0.8" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=6" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" } }, "node_modules/escape-html": { @@ -2665,49 +2138,48 @@ } }, "node_modules/eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -2720,119 +2192,43 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2841,23 +2237,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -2866,15 +2249,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -2887,7 +2261,7 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", @@ -2896,14 +2270,11 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true }, "node_modules/esutils": { "version": "2.0.3", @@ -2923,54 +2294,6 @@ "node": ">= 0.6" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -3054,16 +2377,10 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3109,15 +2426,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3228,6 +2536,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3235,9 +2557,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -3254,22 +2576,13 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": "*" } }, "node_modules/get-intrinsic": { @@ -3287,27 +2600,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3341,9 +2633,9 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3381,10 +2673,10 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/handle-thing": { @@ -3409,967 +2701,322 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/https-localhost": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/https-localhost/-/https-localhost-4.7.1.tgz", - "integrity": "sha512-rl+NFV0l67/0W7fZwk4LB5gS6HdhtSFLpCpf1N+KD5WQAXtPXX1QE8H0cP8VNJii18rtpTkE9eAHdUfJ0goAnQ==", - "dev": true, - "dependencies": { - "appdata-path": "^1.0.0", - "compression": "^1.7.4", - "cors": "^2.8.5", - "express": "^4.17.1", - "spdy": "^4.0.2", - "uglify-js": "^3.15.1" - }, - "bin": { - "serve": "index.js" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz", - "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==", - "dev": true, - "dependencies": { - "@jest/core": "^29.3.1", - "@jest/types": "^29.3.1", - "import-local": "^3.0.2", - "jest-cli": "^29.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-canvas-mock": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz", - "integrity": "sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ==", - "dev": true, - "dependencies": { - "cssfontparser": "^1.2.1", - "moo-color": "^1.0.2" - } - }, - "node_modules/jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz", - "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "p-limit": "^3.1.0", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, + "dev": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-cli": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz", - "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "dependencies": { - "@jest/core": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz", - "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.3.1", - "@jest/types": "^29.3.1", - "babel-jest": "^29.3.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.3.1", - "jest-environment-node": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-diff": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", - "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "bin": { + "he": "bin/he" } }, - "node_modules/jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, - "node_modules/jest-each": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz", - "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==", + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.3.1", - "pretty-format": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/jest-environment-node": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz", - "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==", + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "safe-buffer": "~5.1.0" } }, - "node_modules/jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true }, - "node_modules/jest-haste-map": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz", - "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==", + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", - "micromatch": "^4.0.4", - "walker": "^1.0.8" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "node": ">= 0.8" } }, - "node_modules/jest-leak-detector": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz", - "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==", + "node_modules/https-localhost": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/https-localhost/-/https-localhost-4.7.1.tgz", + "integrity": "sha512-rl+NFV0l67/0W7fZwk4LB5gS6HdhtSFLpCpf1N+KD5WQAXtPXX1QE8H0cP8VNJii18rtpTkE9eAHdUfJ0goAnQ==", "dev": true, "dependencies": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "appdata-path": "^1.0.0", + "compression": "^1.7.4", + "cors": "^2.8.5", + "express": "^4.17.1", + "spdy": "^4.0.2", + "uglify-js": "^3.15.1" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "bin": { + "serve": "index.js" } }, - "node_modules/jest-matcher-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", - "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-message-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", - "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.3.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 4" } }, - "node_modules/jest-mock": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", - "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "jest-util": "^29.3.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, "engines": { "node": ">=6" }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-resolve": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz", - "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.8.19" } }, - "node_modules/jest-resolve-dependencies": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz", - "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/jest-runner": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz", - "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "dependencies": { - "@jest/console": "^29.3.1", - "@jest/environment": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-leak-detector": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-resolve": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-util": "^29.3.1", - "jest-watcher": "^29.3.1", - "jest-worker": "^29.3.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.10" } }, - "node_modules/jest-runtime": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz", - "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==", + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, "dependencies": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/globals": "^29.3.1", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "has": "^1.0.3" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-snapshot": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz", - "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.3.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "natural-compare": "^1.4.0", - "pretty-format": "^29.3.1", - "semver": "^7.3.5" - }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-validate": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz", - "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "dependencies": { - "@jest/types": "^29.3.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "leven": "^3.1.0", - "pretty-format": "^29.3.1" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.12.0" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/jest-watcher": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz", - "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.3.1", - "string-length": "^4.0.1" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/jest-worker": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", - "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { - "@types/node": "*", - "jest-util": "^29.3.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8" } }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", "dev": true }, "node_modules/js-yaml": { @@ -4384,24 +3031,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4414,41 +3043,26 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "engines": { - "node": ">=6" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true }, "node_modules/levn": { "version": "0.4.1", @@ -4463,11 +3077,21 @@ "node": ">= 0.8.0" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } }, "node_modules/locate-path": { "version": "6.0.0", @@ -4484,10 +3108,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", "dev": true }, "node_modules/lodash.merge": { @@ -4496,6 +3132,15 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -4508,43 +3153,48 @@ "node": ">=10" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/magicast": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.2.tgz", + "integrity": "sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "source-map-js": "^1.0.2" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "tmpl": "1.0.5" + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/media-typer": { @@ -4632,15 +3282,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -4659,13 +3300,16 @@ "node": "*" } }, - "node_modules/moo-color": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", - "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==", + "node_modules/mlly": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", + "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==", "dev": true, "dependencies": { - "color-name": "^1.1.4" + "acorn": "^8.10.0", + "pathe": "^1.1.1", + "pkg-types": "^1.0.3", + "ufo": "^1.3.0" } }, "node_modules/ms": { @@ -4674,6 +3318,30 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4689,39 +3357,6 @@ "node": ">= 0.6" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4776,33 +3411,18 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -4838,15 +3458,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4859,24 +3470,6 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -4886,6 +3479,12 @@ "node": ">= 0.8" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4934,6 +3533,21 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", + "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -4952,77 +3566,43 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", "dev": true, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/postcss": { + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "p-limit": "^2.2.0" + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14" } }, "node_modules/prelude-ls": { @@ -5034,40 +3614,13 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -5091,20 +3644,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } + "dev": true }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -5120,9 +3660,9 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -5216,27 +3756,6 @@ "node": ">= 6" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -5254,27 +3773,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -5284,15 +3782,6 @@ "node": ">=4" } }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5318,6 +3807,38 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.4.tgz", + "integrity": "sha512-2ztU7pY/lrQyXSCnnoU4ICjT/tCG9cdH3/G25ERqE3Lst6vl2BCM5hL2Nw+sslAvAf+ccKsAq1SkKQALyqhR7g==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.9.4", + "@rollup/rollup-android-arm64": "4.9.4", + "@rollup/rollup-darwin-arm64": "4.9.4", + "@rollup/rollup-darwin-x64": "4.9.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.4", + "@rollup/rollup-linux-arm64-gnu": "4.9.4", + "@rollup/rollup-linux-arm64-musl": "4.9.4", + "@rollup/rollup-linux-riscv64-gnu": "4.9.4", + "@rollup/rollup-linux-x64-gnu": "4.9.4", + "@rollup/rollup-linux-x64-musl": "4.9.4", + "@rollup/rollup-win32-arm64-msvc": "4.9.4", + "@rollup/rollup-win32-ia32-msvc": "4.9.4", + "@rollup/rollup-win32-x64-msvc": "4.9.4", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5360,9 +3881,9 @@ "dev": true }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5475,16 +3996,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, "node_modules/slash": { @@ -5505,14 +4020,13 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=0.10.0" } }, "node_modules/spdy": { @@ -5551,26 +4065,11 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true }, "node_modules/statuses": { "version": "2.0.1", @@ -5581,6 +4080,12 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -5610,434 +4115,689 @@ } ] }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "dev": true, + "dependencies": { + "acorn": "^8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/tinybench": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", + "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz", + "integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz", + "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==", + "dev": true, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/strip-final-newline": { + "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, "engines": { - "node": ">=8" + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", + "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">= 4.0.0" } }, - "node_modules/supports-preserve-symlinks-flag": { + "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" + "punycode": "^2.1.0" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.4.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "dependencies": { - "is-number": "^7.0.0" + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=10.12.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "dev": true, "engines": { - "node": ">=0.6" + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" } }, - "node_modules/ts-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz", - "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==", + "node_modules/vite": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz", + "integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==", "dev": true, "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.1", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" + "esbuild": "^0.19.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" }, "bin": { - "ts-jest": "cli.js" + "vite": "bin/vite.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" }, "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3" + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" }, "peerDependenciesMeta": { - "@babel/core": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { "optional": true }, - "@jest/types": { + "sass": { "optional": true }, - "babel-jest": { + "stylus": { "optional": true }, - "esbuild": { + "sugarss": { + "optional": true + }, + "terser": { "optional": true } } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "node_modules/vite-node": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.1.3.tgz", + "integrity": "sha512-BLSO72YAkIUuNrOx+8uznYICJfTEbvBAmWClY3hpath5+h1mbPS5OMn42lrTxXuyCazVyZoDkSRnju78GiVCqA==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-plugin-dts": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.7.0.tgz", + "integrity": "sha512-np1uPaYzu98AtPReB8zkMnbjwcNHOABsLhqVOf81b3ol9b5M2wPcAVs8oqPnOpr6Us+7yDXVauwkxsk5+ldmRA==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor": "7.39.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/language-core": "^1.8.26", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "vue-tsc": "^1.8.26" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" + "typescript": "*", + "vite": "*" }, "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { + "vite": { "optional": true } } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/vite-plugin-eslint": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/vite-plugin-eslint/-/vite-plugin-eslint-1.8.1.tgz", + "integrity": "sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==", "dev": true, "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" + "@rollup/pluginutils": "^4.2.1", + "@types/eslint": "^8.4.5", + "rollup": "^2.77.2" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "eslint": ">=7", + "vite": ">=2" } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/vite-plugin-eslint/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1" + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 8.0.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/vite-plugin-eslint/node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, "engines": { - "node": ">=4" + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, + "node_modules/vitest": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.1.3.tgz", + "integrity": "sha512-2l8om1NOkiA90/Y207PsEvJLYygddsOyr81wLQ20Ra8IlLKbyQncWsGZjnbkyG2KwwuTXLQjEPOJuxGMG8qJBQ==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.1.3", + "@vitest/runner": "1.1.3", + "@vitest/snapshot": "1.1.3", + "@vitest/spy": "1.1.3", + "@vitest/utils": "1.1.3", + "acorn-walk": "^8.3.1", + "cac": "^6.7.14", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^1.3.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.1", + "vite": "^5.0.0", + "vite-node": "1.1.3", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, "engines": { - "node": ">=10" + "node": "^18.0.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "^1.0.0", + "@vitest/ui": "^1.0.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/vitest/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "node_modules/vitest/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "engines": { + "node": ">=16" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, "engines": { - "node": ">=4.2.0" + "node": ">=16.17.0" } }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "node_modules/vitest/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, "engines": { - "node": ">=0.8.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "node_modules/vitest/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "node_modules/vitest/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "path-key": "^4.0.0" }, - "bin": { - "browserslist-lint": "cli.js" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/vitest/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "punycode": "^2.1.0" + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/vitest/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, "engines": { - "node": ">= 0.4.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "node_modules/vitest/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "node_modules/vitest/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, "engines": { - "node": ">=10.12.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, - "engines": { - "node": ">= 0.8" + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "node_modules/vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", "dev": true, "dependencies": { - "makeerror": "1.0.12" + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" } }, "node_modules/wbuf": { @@ -6064,30 +4824,20 @@ "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "siginfo": "^2.0.0", + "stackback": "0.0.2" }, - "engines": { - "node": ">=10" + "bin": { + "why-is-node-running": "cli.js" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "engines": { + "node": ">=8" } }, "node_modules/wrappy": { @@ -6096,70 +4846,12 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -6171,504 +4863,266 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dev": true, + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" } }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true }, - "@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true }, - "@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } + "@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" } }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "@esbuild/aix-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz", + "integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==", "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } + "optional": true }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "@esbuild/android-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz", + "integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==", "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } + "optional": true }, - "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "@esbuild/android-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz", + "integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==", "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true + "optional": true }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "@esbuild/android-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz", + "integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==", "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } + "optional": true }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "@esbuild/darwin-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz", + "integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==", "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true + "optional": true }, - "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "@esbuild/darwin-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz", + "integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==", "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - } + "optional": true }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "@esbuild/freebsd-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz", + "integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true + "optional": true }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "@esbuild/freebsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz", + "integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "@esbuild/linux-arm": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz", + "integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "@esbuild/linux-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz", + "integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } + "optional": true }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "@esbuild/linux-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz", + "integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } + "optional": true }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "@esbuild/linux-loong64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz", + "integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "@esbuild/linux-mips64el": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz", + "integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } + "optional": true }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "@esbuild/linux-ppc64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz", + "integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } + "optional": true }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "@esbuild/linux-riscv64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz", + "integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "@esbuild/linux-s390x": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz", + "integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } + "optional": true }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "@esbuild/linux-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz", + "integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "@esbuild/netbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz", + "integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "@esbuild/openbsd-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz", + "integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } + "optional": true }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "@esbuild/sunos-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz", + "integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } + "optional": true }, - "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "@esbuild/win32-arm64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz", + "integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } + "optional": true }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "@esbuild/win32-ia32": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz", + "integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==", "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } + "optional": true }, - "@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", + "@esbuild/win32-x64": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz", + "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==", "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } + "optional": true }, - "@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" + "eslint-visitor-keys": "^3.3.0" } }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -6676,13 +5130,19 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" } @@ -6694,355 +5154,35 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, "@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "@jest/console": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz", - "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz", - "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==", - "dev": true, - "requires": { - "@jest/console": "^29.3.1", - "@jest/reporters": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-resolve-dependencies": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "jest-watcher": "^29.3.1", - "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/create-cache-key-function": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz", - "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1" - }, - "dependencies": { - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - } - } - }, - "@jest/environment": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", - "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "jest-mock": "^29.3.1" - } - }, - "@jest/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==", - "dev": true, - "requires": { - "expect": "^29.3.1", - "jest-snapshot": "^29.3.1" - } - }, - "@jest/expect-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", - "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", - "dev": true, - "requires": { - "jest-get-type": "^29.2.0" - } - }, - "@jest/fake-timers": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", - "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" - } - }, - "@jest/globals": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz", - "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==", - "dev": true, - "requires": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/types": "^29.3.1", - "jest-mock": "^29.3.1" - } - }, - "@jest/reporters": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz", - "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - } - }, "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.24.1" - } - }, - "@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz", - "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==", - "dev": true, - "requires": { - "@jest/console": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz", - "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==", - "dev": true, - "requires": { - "@jest/test-result": "^29.3.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz", - "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.3.1", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - } - }, - "@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@sinclair/typebox": "^0.27.8" } }, "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" } }, "@jridgewell/resolve-uri": { @@ -7073,6 +5213,67 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@microsoft/api-extractor": { + "version": "7.39.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.39.0.tgz", + "integrity": "sha512-PuXxzadgnvp+wdeZFPonssRAj/EW4Gm4s75TXzPk09h3wJ8RS3x7typf95B4vwZRrPTQBGopdUl+/vHvlPdAcg==", + "dev": true, + "requires": { + "@microsoft/api-extractor-model": "7.28.3", + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "3.62.0", + "@rushstack/rig-package": "0.5.1", + "@rushstack/ts-command-line": "4.17.1", + "colors": "~1.2.1", + "lodash": "~4.17.15", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.3.3" + } + }, + "@microsoft/api-extractor-model": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.3.tgz", + "integrity": "sha512-wT/kB2oDbdZXITyDh2SQLzaWwTOFbV326fP0pUwNW00WeliARs0qjmXBWmGWardEzp2U3/axkO3Lboqun6vrig==", + "dev": true, + "requires": { + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "3.62.0" + } + }, + "@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true + }, + "@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", + "dev": true, + "requires": { + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + }, + "dependencies": { + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7099,384 +5300,541 @@ "fastq": "^1.6.0" } }, - "@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true - }, - "@sinonjs/commons": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", - "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", + "@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", "dev": true, "requires": { - "type-detect": "4.0.8" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" } }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "@rollup/rollup-android-arm-eabi": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.4.tgz", + "integrity": "sha512-ub/SN3yWqIv5CWiAZPHVS1DloyZsJbtXmX4HxUTIpS0BHm9pW5iYBo2mIZi+hE3AeiTzHz33blwSnhdUo+9NpA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.4.tgz", + "integrity": "sha512-ehcBrOR5XTl0W0t2WxfTyHCR/3Cq2jfb+I4W+Ch8Y9b5G+vbAecVv0Fx/J1QKktOrgUYsIKxWAKgIpvw56IFNA==", "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } + "optional": true }, - "@swc/core": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.24.tgz", - "integrity": "sha512-QMOTd0AgiUT3K1crxLRqd3gw0f3FC8hhH1vvlIlryvYqU4c+FJ/T2G4ZhMKLxQlZ/jX6Rhk0gKINZRBxy2GFyQ==", + "@rollup/rollup-darwin-arm64": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.4.tgz", + "integrity": "sha512-1fzh1lWExwSTWy8vJPnNbNM02WZDS8AW3McEOb7wW+nPChLKf3WG2aG7fhaUmfX5FKw9zhsF5+MBwArGyNM7NA==", "dev": true, - "requires": { - "@swc/core-darwin-arm64": "1.3.24", - "@swc/core-darwin-x64": "1.3.24", - "@swc/core-linux-arm-gnueabihf": "1.3.24", - "@swc/core-linux-arm64-gnu": "1.3.24", - "@swc/core-linux-arm64-musl": "1.3.24", - "@swc/core-linux-x64-gnu": "1.3.24", - "@swc/core-linux-x64-musl": "1.3.24", - "@swc/core-win32-arm64-msvc": "1.3.24", - "@swc/core-win32-ia32-msvc": "1.3.24", - "@swc/core-win32-x64-msvc": "1.3.24" - } + "optional": true }, - "@swc/core-darwin-arm64": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.24.tgz", - "integrity": "sha512-rR+9UpWm+fGXcipsjCst2hIL1GYIbo0YTLhJZWdIpQD6KRHHJMFXiydMgQQkDj2Ml7HpqUVgxj6m4ZWYL8b0OA==", + "@rollup/rollup-darwin-x64": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.4.tgz", + "integrity": "sha512-Gc6cukkF38RcYQ6uPdiXi70JB0f29CwcQ7+r4QpfNpQFVHXRd0DfWFidoGxjSx1DwOETM97JPz1RXL5ISSB0pA==", "dev": true, "optional": true }, - "@swc/core-darwin-x64": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.24.tgz", - "integrity": "sha512-px+5vkGtgPH0m3FkkTBHynlRdS5rRz+lK+wiXIuBZFJSySWFl6RkKbvwkD+sf0MpazQlqwlv/rTOGJBw6oDffg==", + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.4.tgz", + "integrity": "sha512-g21RTeFzoTl8GxosHbnQZ0/JkuFIB13C3T7Y0HtKzOXmoHhewLbVTFBQZu+z5m9STH6FZ7L/oPgU4Nm5ErN2fw==", "dev": true, "optional": true }, - "@swc/core-linux-arm-gnueabihf": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.24.tgz", - "integrity": "sha512-jLs8ZOdTV4UW4J12E143QJ4mOMONQtqgAnuhBbRuWFzQ3ny1dfoC3P1jNWAJ2Xi59XdxAIXn0PggPNH4Kh34kw==", + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.4.tgz", + "integrity": "sha512-TVYVWD/SYwWzGGnbfTkrNpdE4HON46orgMNHCivlXmlsSGQOx/OHHYiQcMIOx38/GWgwr/po2LBn7wypkWw/Mg==", "dev": true, "optional": true }, - "@swc/core-linux-arm64-gnu": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.24.tgz", - "integrity": "sha512-A/v0h70BekrwGpp1DlzIFGcHQ3QQ2PexXcnnuIBZeMc9gNmHlcZmg3EcwAnaUDiokhNuSUFA/wV94yk1OqmSkw==", + "@rollup/rollup-linux-arm64-musl": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.4.tgz", + "integrity": "sha512-XcKvuendwizYYhFxpvQ3xVpzje2HHImzg33wL9zvxtj77HvPStbSGI9czrdbfrf8DGMcNNReH9pVZv8qejAQ5A==", "dev": true, "optional": true }, - "@swc/core-linux-arm64-musl": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.24.tgz", - "integrity": "sha512-pbc9eArWPTiMrbpS/pJo0IiQNAKAQBcBIDjWBGP1tcw2iDXYLw4bruwz9kI/VjakbshWb8MoE4T5ClkeuULvSw==", + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.4.tgz", + "integrity": "sha512-LFHS/8Q+I9YA0yVETyjonMJ3UA+DczeBd/MqNEzsGSTdNvSJa1OJZcSH8GiXLvcizgp9AlHs2walqRcqzjOi3A==", "dev": true, "optional": true }, - "@swc/core-linux-x64-gnu": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.24.tgz", - "integrity": "sha512-pP5pOLlY1xd352qo7rTlpVPUI9/9VhOd4b3Lk+LzfZDq9bTL2NDlGfyrPiwa5DGHMSzrugH56K2J68eutkxYVA==", + "@rollup/rollup-linux-x64-gnu": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.4.tgz", + "integrity": "sha512-dIYgo+j1+yfy81i0YVU5KnQrIJZE8ERomx17ReU4GREjGtDW4X+nvkBak2xAUpyqLs4eleDSj3RrV72fQos7zw==", "dev": true, "optional": true }, - "@swc/core-linux-x64-musl": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.24.tgz", - "integrity": "sha512-phNbP7zGp+Wcyxq1Qxlpe5KkxO7WLT2kVQUC7aDFGlVdCr+xdXsfH1MzheHtnr0kqTVQX1aiM8XXXHfFxR0oNA==", + "@rollup/rollup-linux-x64-musl": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.4.tgz", + "integrity": "sha512-RoaYxjdHQ5TPjaPrLsfKqR3pakMr3JGqZ+jZM0zP2IkDtsGa4CqYaWSfQmZVgFUCgLrTnzX+cnHS3nfl+kB6ZQ==", "dev": true, "optional": true }, - "@swc/core-win32-arm64-msvc": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.24.tgz", - "integrity": "sha512-qhbiJTWAOqyR+K9xnGmCkOWSz2EmWpDBstEJCEOTc6FZiEdbiTscDmqTcMbCKaTHGu8t+6erVA4t65/Eg6uWPA==", + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.4.tgz", + "integrity": "sha512-T8Q3XHV+Jjf5e49B4EAaLKV74BbX7/qYBRQ8Wop/+TyyU0k+vSjiLVSHNWdVd1goMjZcbhDmYZUYW5RFqkBNHQ==", "dev": true, "optional": true }, - "@swc/core-win32-ia32-msvc": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.24.tgz", - "integrity": "sha512-JfghIlscE4Rz+Lc08lSoDh+R0cWxrISed5biogFfE6vZqhaDnw3E5Qshqw7O3pIaiq8L2u1nmzuyP581ZmpbRA==", + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.4.tgz", + "integrity": "sha512-z+JQ7JirDUHAsMecVydnBPWLwJjbppU+7LZjffGf+Jvrxq+dVjIE7By163Sc9DKc3ADSU50qPVw0KonBS+a+HQ==", "dev": true, "optional": true }, - "@swc/core-win32-x64-msvc": { - "version": "1.3.24", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.24.tgz", - "integrity": "sha512-3AmJRr0hwciwDBbzUNqaftvppzS8v9X/iv/Wl7YaVLBVpPfQvaZzfqLycvNMGLZb5vIKXR/u58txg3dRBGsJtw==", + "@rollup/rollup-win32-x64-msvc": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.4.tgz", + "integrity": "sha512-LfdGXCV9rdEify1oxlN9eamvDSjv9md9ZVMAbNHA87xqIfFCxImxan9qZ8+Un54iK2nnqPlbnSi4R54ONtbWBw==", "dev": true, "optional": true }, - "@swc/jest": { - "version": "0.2.24", - "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.24.tgz", - "integrity": "sha512-fwgxQbM1wXzyKzl1+IW0aGrRvAA8k0Y3NxFhKigbPjOJ4mCKnWEcNX9HQS3gshflcxq8YKhadabGUVfdwjCr6Q==", + "@rushstack/node-core-library": { + "version": "3.62.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz", + "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==", + "dev": true, + "requires": { + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" + } + }, + "@rushstack/rig-package": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", + "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", + "dev": true, + "requires": { + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" + } + }, + "@rushstack/ts-command-line": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz", + "integrity": "sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==", "dev": true, "requires": { - "@jest/create-cache-key-function": "^27.4.2", - "jsonc-parser": "^3.2.0" + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + } } }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", "dev": true }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "@types/eslint": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.1.tgz", + "integrity": "sha512-18PLWRzhy9glDQp3+wOgfLYRWlhgX0azxgJ63rdpoUHyrC9z0f5CkFburjQx4uD7ZCruw85ZtMt6K+L+R8fLJQ==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "@types/node": { + "version": "20.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.7.tgz", + "integrity": "sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "undici-types": "~5.26.4" } }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "@types/w3c-web-usb": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz", + "integrity": "sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.0.tgz", + "integrity": "sha512-3lqEvQUdCozi6d1mddWqd+kf8KxmGq2Plzx36BlkjuQe3rSTm/O98cLf0A4uDO+a5N1KD2SeEEl6fW97YHY+6w==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.18.0", + "@typescript-eslint/type-utils": "6.18.0", + "@typescript-eslint/utils": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" } }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "@typescript-eslint/parser": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.0.tgz", + "integrity": "sha512-v6uR68SFvqhNQT41frCMCQpsP+5vySy6IdgjlzUWoo7ALCnpaWYcz/Ij2k4L8cEsL0wkvOviCMpjmtRtHNOKzA==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@typescript-eslint/scope-manager": "6.18.0", + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/typescript-estree": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0", + "debug": "^4.3.4" } }, - "@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "@typescript-eslint/scope-manager": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.0.tgz", + "integrity": "sha512-o/UoDT2NgOJ2VfHpfr+KBY2ErWvCySNUIX/X7O9g8Zzt/tXdpfEU43qbNk8LVuWUT2E0ptzTWXh79i74PP0twA==", "dev": true, "requires": { - "@babel/types": "^7.3.0" + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0" } }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "@typescript-eslint/type-utils": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.0.tgz", + "integrity": "sha512-ZeMtrXnGmTcHciJN1+u2CigWEEXgy1ufoxtWcHORt5kGvpjjIlK9MUhzHm4RM8iVy6dqSaZA/6PVkX6+r+ChjQ==", "dev": true, "requires": { - "@types/node": "*" + "@typescript-eslint/typescript-estree": "6.18.0", + "@typescript-eslint/utils": "6.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" } }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "@typescript-eslint/types": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.0.tgz", + "integrity": "sha512-/RFVIccwkwSdW/1zeMx3hADShWbgBxBnV/qSrex6607isYjj05t36P6LyONgqdUrNLl5TYU8NIKdHUYpFvExkA==", "dev": true }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "@typescript-eslint/typescript-estree": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.0.tgz", + "integrity": "sha512-klNvl+Ql4NsBNGB4W9TZ2Od03lm7aGvTbs0wYaFYsplVPhr+oeXjlPZCDI4U9jgJIDK38W1FKhacCFzCC+nbIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/visitor-keys": "6.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.0.tgz", + "integrity": "sha512-wiKKCbUeDPGaYEYQh1S580dGxJ/V9HI7K5sbGAVklyf+o5g3O+adnS4UNJajplF4e7z2q0uVBaTdT/yLb4XAVA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.18.0", + "@typescript-eslint/types": "6.18.0", + "@typescript-eslint/typescript-estree": "6.18.0", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.0.tgz", + "integrity": "sha512-1wetAlSZpewRDb2h9p/Q8kRjdGuqdTAQbkJIOUMLug2LBLG+QOjiWoSj6/3B/hA9/tVTFFdtiKvAYoYnSRW/RA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.18.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "@vitest/coverage-v8": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.1.3.tgz", + "integrity": "sha512-Uput7t3eIcbSTOTQBzGtS+0kah96bX+szW9qQrLeGe3UmgL2Akn8POnyC2lH7XsnREZOds9aCUTxgXf+4HX5RA==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.1", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.2", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.2.0" + } + }, + "@vitest/expect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.1.3.tgz", + "integrity": "sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*" + "@vitest/spy": "1.1.3", + "@vitest/utils": "1.1.3", + "chai": "^4.3.10" } }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "@vitest/runner": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.1.3.tgz", + "integrity": "sha512-Va2XbWMnhSdDEh/OFxyUltgQuuDRxnarK1hW5QNN4URpQrqq6jtt8cfww/pQQ4i0LjoYxh/3bYWvDFlR9tU73g==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@vitest/utils": "1.1.3", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "dependencies": { + "p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } } }, - "@types/jest": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.2.tgz", - "integrity": "sha512-og1wAmdxKoS71K2ZwSVqWPX6OVn3ihZ6ZT2qvZvZQm90lJVDyXIjYcu4Khx2CNIeaFv12rOU/YObOsI3VOkzog==", + "@vitest/snapshot": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.1.3.tgz", + "integrity": "sha512-U0r8pRXsLAdxSVAyGNcqOU2H3Z4Y2dAAGGelL50O0QRMdi1WWeYHdrH/QWpN1e8juWfVKsb8B+pyJwTC+4Gy9w==", "dev": true, "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" } }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", - "dev": true - }, - "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true - }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/w3c-web-usb": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/w3c-web-usb/-/w3c-web-usb-1.0.6.tgz", - "integrity": "sha512-cSjhgrr8g4KbPnnijAr/KJDNKa/bBa+ixYkywFRvrhvi9n1WEl7yYbtRyzE6jqNQiSxxJxoAW3STaOQwJHndaw==", - "dev": true - }, - "@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "@vitest/spy": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.1.3.tgz", + "integrity": "sha512-Ec0qWyGS5LhATFQtldvChPTAHv08yHIOZfiNcjwRQbFPHpkih0md9KAbs7TfeIfL7OFKoe7B/6ukBTqByubXkQ==", "dev": true, "requires": { - "@types/yargs-parser": "*" + "tinyspy": "^2.2.0" } }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.41.0.tgz", - "integrity": "sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==", + "@vitest/utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.1.3.tgz", + "integrity": "sha512-Dyt3UMcdElTll2H75vhxfpZu03uFpXRCHxWnzcrFjZxT1kTbq8ALUYIeBgGolo1gldVdI0YSlQRacsqxTwNqwg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/type-utils": "5.41.0", - "@typescript-eslint/utils": "5.41.0", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "dependencies": { + "estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0" + } + } } }, - "@typescript-eslint/parser": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.41.0.tgz", - "integrity": "sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==", + "@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "debug": "^4.3.4" + "@volar/source-map": "1.11.1" } }, - "@typescript-eslint/scope-manager": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.41.0.tgz", - "integrity": "sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==", + "@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0" + "muggle-string": "^0.3.1" } }, - "@typescript-eslint/type-utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.41.0.tgz", - "integrity": "sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==", + "@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.41.0", - "@typescript-eslint/utils": "5.41.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" } }, - "@typescript-eslint/types": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.41.0.tgz", - "integrity": "sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz", - "integrity": "sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==", + "@vue/compiler-core": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.5.tgz", + "integrity": "sha512-Daka7P1z2AgKjzuueWXhwzIsKu0NkLB6vGbNVEV2iJ8GJTrzraZo/Sk4GWCMRtd/qVi3zwnk+Owbd/xSZbwHtQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/visitor-keys": "5.41.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@babel/parser": "^7.23.6", + "@vue/shared": "3.4.5", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" } }, - "@typescript-eslint/utils": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.41.0.tgz", - "integrity": "sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==", + "@vue/compiler-dom": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.5.tgz", + "integrity": "sha512-J8YlxknJVd90SXFJ4HwGANSAXsx5I0lK30sO/zvYV7s5gXf7gZR7r/1BmZ2ju7RGH1lnc6bpBc6nL61yW+PsAQ==", "dev": true, "requires": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.41.0", - "@typescript-eslint/types": "5.41.0", - "@typescript-eslint/typescript-estree": "5.41.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" + "@vue/compiler-core": "3.4.5", + "@vue/shared": "3.4.5" } }, - "@typescript-eslint/visitor-keys": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.41.0.tgz", - "integrity": "sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==", + "@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.41.0", - "eslint-visitor-keys": "^3.3.0" + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, + "@vue/shared": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.5.tgz", + "integrity": "sha512-6XptuzlMvN4l4cDnDw36pdGEV+9njYkQ1ZE0Q6iZLwrKefKaOJyiFmcP3/KBDHbt72cJZGtllAc1GaHe6XGAyg==", + "dev": true + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -7488,9 +5846,9 @@ } }, "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -7501,9 +5859,9 @@ "requires": {} }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", "dev": true }, "ajv": { @@ -7518,23 +5876,6 @@ "uri-js": "^4.2.2" } }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -7550,28 +5891,12 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "appdata-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/appdata-path/-/appdata-path-1.0.0.tgz", "integrity": "sha512-ZbH3ezXfnT/YE3NdqduIt4lBV+H0ybvA2Qx3K76gIjQvh8gROpDFdDLpx6B1QJtW7zxisCbpTlCLhKqoR8cDBw==", "dev": true }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7590,75 +5915,11 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "babel-jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", - "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==", - "dev": true, - "requires": { - "@jest/transform": "^29.3.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.2.0", - "babel-preset-current-node-syntax": "^1.0.0" - } + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true }, "balanced-match": { "version": "1.0.2", @@ -7728,48 +5989,18 @@ "fill-range": "^7.0.1" } }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true }, + "cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -7786,17 +6017,20 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true + "chai": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.0.tgz", + "integrity": "sha512-x9cHNq1uvkCdU+5xTkNh5WtgD4e4yDFCsp9jVc7N7qVeKeftv3gO/ZrviX5d+3ZfxdYnZXZYujjRInu1RogU6A==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + } }, "chalk": { "version": "4.1.2", @@ -7808,47 +6042,15 @@ "supports-color": "^7.1.0" } }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.6.1.tgz", - "integrity": "sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "get-func-name": "^2.0.2" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7864,6 +6066,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true + }, + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "optional": true + }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -7905,6 +6120,12 @@ } } }, + "computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -7968,12 +6189,6 @@ "vary": "^1" } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7985,10 +6200,10 @@ "which": "^2.0.1" } }, - "cssfontparser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz", - "integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==", + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", "dev": true }, "debug": { @@ -8000,11 +6215,14 @@ "ms": "2.1.2" } }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } }, "deep-is": { "version": "0.1.4", @@ -8012,12 +6230,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -8030,28 +6242,16 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, "detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "diff-sequences": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", - "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true }, "dir-glob": { @@ -8078,45 +6278,49 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true + }, + "esbuild": { + "version": "0.19.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz", + "integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.11", + "@esbuild/android-arm": "0.19.11", + "@esbuild/android-arm64": "0.19.11", + "@esbuild/android-x64": "0.19.11", + "@esbuild/darwin-arm64": "0.19.11", + "@esbuild/darwin-x64": "0.19.11", + "@esbuild/freebsd-arm64": "0.19.11", + "@esbuild/freebsd-x64": "0.19.11", + "@esbuild/linux-arm": "0.19.11", + "@esbuild/linux-arm64": "0.19.11", + "@esbuild/linux-ia32": "0.19.11", + "@esbuild/linux-loong64": "0.19.11", + "@esbuild/linux-mips64el": "0.19.11", + "@esbuild/linux-ppc64": "0.19.11", + "@esbuild/linux-riscv64": "0.19.11", + "@esbuild/linux-s390x": "0.19.11", + "@esbuild/linux-x64": "0.19.11", + "@esbuild/netbsd-x64": "0.19.11", + "@esbuild/openbsd-x64": "0.19.11", + "@esbuild/sunos-x64": "0.19.11", + "@esbuild/win32-arm64": "0.19.11", + "@esbuild/win32-ia32": "0.19.11", + "@esbuild/win32-x64": "0.19.11" } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -8130,151 +6334,85 @@ "dev": true }, "eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" - }, - "dependencies": { - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} - }, - "eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" } }, "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } + "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, "esrecurse": { @@ -8284,20 +6422,18 @@ "dev": true, "requires": { "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "esutils": { @@ -8312,42 +6448,6 @@ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1" - } - }, "express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -8416,16 +6516,10 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -8467,15 +6561,6 @@ "reusify": "^1.0.4" } }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -8564,6 +6649,17 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -8571,9 +6667,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -8583,16 +6679,10 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { @@ -8607,18 +6697,6 @@ "has-symbols": "^1.0.3" } }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8643,9 +6721,9 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8671,10 +6749,10 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "handle-thing": { @@ -8710,6 +6788,12 @@ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -8787,12 +6871,6 @@ "uglify-js": "^3.15.1" } }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -8803,9 +6881,9 @@ } }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true }, "import-fresh": { @@ -8818,15 +6896,11 @@ "resolve-from": "^4.0.0" } }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true }, "imurmurhash": { "version": "0.1.4", @@ -8856,12 +6930,6 @@ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, "is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -8877,18 +6945,6 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -8910,12 +6966,6 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -8929,40 +6979,19 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, @@ -8978,464 +7007,19 @@ } }, "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, - "jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz", - "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==", - "dev": true, - "requires": { - "@jest/core": "^29.3.1", - "@jest/types": "^29.3.1", - "import-local": "^3.0.2", - "jest-cli": "^29.3.1" - } - }, - "jest-canvas-mock": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz", - "integrity": "sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ==", - "dev": true, - "requires": { - "cssfontparser": "^1.2.1", - "moo-color": "^1.0.2" - } - }, - "jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - } - }, - "jest-circus": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz", - "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==", - "dev": true, - "requires": { - "@jest/environment": "^29.3.1", - "@jest/expect": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "p-limit": "^3.1.0", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-cli": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz", - "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==", - "dev": true, - "requires": { - "@jest/core": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz", - "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.3.1", - "@jest/types": "^29.3.1", - "babel-jest": "^29.3.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.3.1", - "jest-environment-node": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-runner": "^29.3.1", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", - "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - } - }, - "jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz", - "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.3.1", - "pretty-format": "^29.3.1" - } - }, - "jest-environment-node": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz", - "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==", - "dev": true, - "requires": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "jest-mock": "^29.3.1", - "jest-util": "^29.3.1" - } - }, - "jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", - "dev": true - }, - "jest-haste-map": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz", - "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.3.1", - "jest-worker": "^29.3.1", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-leak-detector": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz", - "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==", - "dev": true, - "requires": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - } - }, - "jest-matcher-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", - "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - } - }, - "jest-message-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", - "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.3.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", - "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "jest-util": "^29.3.1" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", - "dev": true - }, - "jest-resolve": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz", - "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.3.1", - "jest-validate": "^29.3.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz", - "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==", - "dev": true, - "requires": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.3.1" - } - }, - "jest-runner": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz", - "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==", - "dev": true, - "requires": { - "@jest/console": "^29.3.1", - "@jest/environment": "^29.3.1", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.3.1", - "jest-haste-map": "^29.3.1", - "jest-leak-detector": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-resolve": "^29.3.1", - "jest-runtime": "^29.3.1", - "jest-util": "^29.3.1", - "jest-watcher": "^29.3.1", - "jest-worker": "^29.3.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - } - }, - "jest-runtime": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz", - "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==", - "dev": true, - "requires": { - "@jest/environment": "^29.3.1", - "@jest/fake-timers": "^29.3.1", - "@jest/globals": "^29.3.1", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-mock": "^29.3.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.3.1", - "jest-snapshot": "^29.3.1", - "jest-util": "^29.3.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz", - "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.3.1", - "@jest/transform": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.3.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.3.1", - "jest-matcher-utils": "^29.3.1", - "jest-message-util": "^29.3.1", - "jest-util": "^29.3.1", - "natural-compare": "^1.4.0", - "pretty-format": "^29.3.1", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz", - "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==", - "dev": true, - "requires": { - "@jest/types": "^29.3.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "leven": "^3.1.0", - "pretty-format": "^29.3.1" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz", - "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==", - "dev": true, - "requires": { - "@jest/test-result": "^29.3.1", - "@jest/types": "^29.3.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.3.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", - "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.3.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", "dev": true }, "js-yaml": { @@ -9447,18 +7031,6 @@ "argparse": "^2.0.1" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9471,28 +7043,25 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, "jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", "dev": true }, "levn": { @@ -9505,11 +7074,15 @@ "type-check": "~0.4.0" } }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "requires": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + } }, "locate-path": { "version": "6.0.0", @@ -9520,10 +7093,22 @@ "p-locate": "^5.0.0" } }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", "dev": true }, "lodash.merge": { @@ -9532,6 +7117,15 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "requires": { + "get-func-name": "^2.0.1" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -9541,36 +7135,41 @@ "yallist": "^4.0.0" } }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "requires": { - "semver": "^6.0.0" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true } } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "magicast": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.2.tgz", + "integrity": "sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==", + "dev": true, + "requires": { + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "source-map-js": "^1.0.2" + } }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "requires": { - "tmpl": "1.0.5" + "semver": "^7.5.3" } }, "media-typer": { @@ -9634,12 +7233,6 @@ "mime-db": "1.52.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -9655,13 +7248,16 @@ "brace-expansion": "^1.1.7" } }, - "moo-color": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz", - "integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==", + "mlly": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz", + "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==", "dev": true, "requires": { - "color-name": "^1.1.4" + "acorn": "^8.10.0", + "pathe": "^1.1.1", + "pkg-types": "^1.0.3", + "ufo": "^1.3.0" } }, "ms": { @@ -9670,6 +7266,18 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "dev": true + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -9682,33 +7290,6 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9751,27 +7332,18 @@ "wrappy": "1" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { @@ -9792,31 +7364,13 @@ "p-limit": "^3.0.2" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "callsites": "^3.0.0" } }, "parseurl": { @@ -9825,6 +7379,12 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -9861,6 +7421,18 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pathe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", + "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -9873,58 +7445,26 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true + "pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "requires": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "postcss": { + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", "dev": true, "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" } }, "prelude-ls": { @@ -9933,28 +7473,13 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, "pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -9973,16 +7498,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -9994,9 +7509,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "qs": { @@ -10057,18 +7572,6 @@ "util-deprecate": "^1.0.1" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -10080,35 +7583,12 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -10124,6 +7604,29 @@ "glob": "^7.1.3" } }, + "rollup": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.4.tgz", + "integrity": "sha512-2ztU7pY/lrQyXSCnnoU4ICjT/tCG9cdH3/G25ERqE3Lst6vl2BCM5hL2Nw+sslAvAf+ccKsAq1SkKQALyqhR7g==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.9.4", + "@rollup/rollup-android-arm64": "4.9.4", + "@rollup/rollup-darwin-arm64": "4.9.4", + "@rollup/rollup-darwin-x64": "4.9.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.9.4", + "@rollup/rollup-linux-arm64-gnu": "4.9.4", + "@rollup/rollup-linux-arm64-musl": "4.9.4", + "@rollup/rollup-linux-riscv64-gnu": "4.9.4", + "@rollup/rollup-linux-x64-gnu": "4.9.4", + "@rollup/rollup-linux-x64-musl": "4.9.4", + "@rollup/rollup-win32-arm64-msvc": "4.9.4", + "@rollup/rollup-win32-ia32-msvc": "4.9.4", + "@rollup/rollup-win32-x64-msvc": "4.9.4", + "@types/estree": "1.0.5", + "fsevents": "~2.3.2" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10152,9 +7655,9 @@ "dev": true }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -10250,16 +7753,10 @@ "object-inspect": "^1.9.0" } }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, "slash": { @@ -10274,15 +7771,11 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true }, "spdy": { "version": "4.0.2", @@ -10317,22 +7810,11 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } + "stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true }, "statuses": { "version": "2.0.1", @@ -10340,6 +7822,12 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, + "std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -10357,26 +7845,11 @@ } } }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } + "string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true }, "strip-ansi": { "version": "6.0.1", @@ -10387,24 +7860,21 @@ "ansi-regex": "^5.0.1" } }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "strip-literal": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "dev": true, + "requires": { + "acorn": "^8.10.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10437,10 +7907,22 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "tinybench": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", + "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", + "dev": true + }, + "tinypool": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz", + "integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==", + "dev": true + }, + "tinyspy": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz", + "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==", "dev": true }, "to-fast-properties": { @@ -10464,57 +7946,12 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, - "ts-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz", - "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.1", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - } - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", "dev": true, - "requires": { - "tslib": "^1.8.1" - } + "requires": {} }, "type-check": { "version": "0.4.0", @@ -10548,9 +7985,15 @@ } }, "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true + }, + "ufo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", + "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", "dev": true }, "uglify-js": { @@ -10559,22 +8002,24 @@ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -10596,44 +8041,227 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - } + "convert-source-map": "^2.0.0" } }, + "validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "vite": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz", + "integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==", + "dev": true, + "requires": { + "esbuild": "^0.19.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.32", + "rollup": "^4.2.0" + } + }, + "vite-node": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.1.3.tgz", + "integrity": "sha512-BLSO72YAkIUuNrOx+8uznYICJfTEbvBAmWClY3hpath5+h1mbPS5OMn42lrTxXuyCazVyZoDkSRnju78GiVCqA==", + "dev": true, + "requires": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + } + }, + "vite-plugin-dts": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.7.0.tgz", + "integrity": "sha512-np1uPaYzu98AtPReB8zkMnbjwcNHOABsLhqVOf81b3ol9b5M2wPcAVs8oqPnOpr6Us+7yDXVauwkxsk5+ldmRA==", + "dev": true, + "requires": { + "@microsoft/api-extractor": "7.39.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/language-core": "^1.8.26", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "vue-tsc": "^1.8.26" + } + }, + "vite-plugin-eslint": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/vite-plugin-eslint/-/vite-plugin-eslint-1.8.1.tgz", + "integrity": "sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^4.2.1", + "@types/eslint": "^8.4.5", + "rollup": "^2.77.2" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + } + } + }, + "vitest": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.1.3.tgz", + "integrity": "sha512-2l8om1NOkiA90/Y207PsEvJLYygddsOyr81wLQ20Ra8IlLKbyQncWsGZjnbkyG2KwwuTXLQjEPOJuxGMG8qJBQ==", + "dev": true, + "requires": { + "@vitest/expect": "1.1.3", + "@vitest/runner": "1.1.3", + "@vitest/snapshot": "1.1.3", + "@vitest/spy": "1.1.3", + "@vitest/utils": "1.1.3", + "acorn-walk": "^8.3.1", + "cac": "^6.7.14", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^1.3.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.1", + "vite": "^5.0.0", + "vite-node": "1.1.3", + "why-is-node-running": "^2.2.2" + }, + "dependencies": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } + } + }, + "vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", "dev": true, "requires": { - "makeerror": "1.0.12" + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" } }, "wbuf": { @@ -10654,21 +8282,14 @@ "isexe": "^2.0.0" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "siginfo": "^2.0.0", + "stackback": "0.0.2" } }, "wrappy": { @@ -10677,60 +8298,29 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dev": true, + "requires": { + "commander": "^9.4.1", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + } } } } diff --git a/package.json b/package.json index 443dddc..94b8ed2 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,18 @@ { "name": "webzlp", - "version": "1.0.3", - "description": "Zebra LP-series WebUSB driver", - "main": "./dist/src/index.js", - "types": "./dist/src/index.d.ts", - "files": [ - "dist/src/*" - ], - "scripts": { - "build": "npx tsc --declaration", - "test": "npx jest", - "lint": "eslint . --ext .ts", - "lint-and-fix": "eslint . --ext .ts --fix", - "serve-local": "export PORT=4443 || set PORT=4443&& serve ." - }, + "version": "2.0.0-alpha.1", + "description": "A small library using WebUSB to print labels on label printers.", + "type": "module", "repository": { "type": "git", "url": "git+https://github.com/Cellivar/WebZLP.git" }, + "author": "Cellivar Kangaroorat (https://github.com/cellivar)", + "license": "GPL-3.0-only", + "bugs": { + "url": "https://github.com/Cellivar/WebZLP/issues" + }, + "homepage": "https://github.com/Cellivar/WebZLP#readme", "keywords": [ "thermal_printer", "printer", @@ -26,28 +21,35 @@ "lp2844", "lp2824" ], - "author": "Cellivar Kangaroorat (https://github.com/cellivar)", - "license": "GPL-3.0-only", - "bugs": { - "url": "https://github.com/Cellivar/WebZLP/issues" + "scripts": { + "build": "tsc && vite build", + "test": "vitest", + "serve-local": "export PORT=4444 || set PORT=4444 && serve ." }, - "homepage": "https://github.com/Cellivar/WebZLP#readme", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/webzlp.js", + "require": "./dist/webzlp.umd.csj", + "default": "./dist/webzlp.js" + }, + "./readme": "./readme.md" + }, + "files": [ + "dist" + ], "devDependencies": { - "@swc/core": "^1.3.24", - "@swc/jest": "^0.2.24", - "@types/jest": "^29.2.0", - "@types/w3c-web-usb": "^1.0.6", - "@typescript-eslint/eslint-plugin": "^5.41.0", - "@typescript-eslint/parser": "^5.41.0", - "eslint": "^8.26.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.2.1", + "@types/node": "^20.8.9", + "@types/w3c-web-usb": "^1.0.10", + "@typescript-eslint/eslint-plugin": "^6.17.0", + "@typescript-eslint/parser": "^6.17.0", + "@vitest/coverage-v8": "^1.1.3", + "eslint": "^8.56.0", "https-localhost": "^4.7.1", - "jest": "^29.2.2", - "jest-canvas-mock": "^2.4.0", - "prettier": "^2.7.1", - "ts-jest": "^29.0.3", - "ts-node": "^10.9.1", - "typescript": "^4.9.4" + "typescript": "^5.2.2", + "vite": "5.0.11", + "vite-plugin-dts": "3.7.0", + "vite-plugin-eslint": "^1.8.1", + "vitest": "1.1.3" } } diff --git a/src/Color.ts b/src/Color.ts deleted file mode 100644 index 0c22fd2..0000000 --- a/src/Color.ts +++ /dev/null @@ -1,269 +0,0 @@ -type ColorKeyword = - | 'black' - | 'silver' - | 'gray' - | 'white' - | 'maroon' - | 'red' - | 'purple' - | 'fuchsia' - | 'green' - | 'lime' - | 'olive' - | 'yellow' - | 'navy' - | 'blue' - | 'teal' - | 'aqua' - | 'orange' - | 'aliceblue' - | 'antiquewhite' - | 'aquamarine' - | 'azure' - | 'beige' - | 'bisque' - | 'blanchedalmond' - | 'blueviolet' - | 'brown' - | 'burlywood' - | 'cadetblue' - | 'chartreuse' - | 'chocolate' - | 'coral' - | 'cornflowerblue' - | 'cornsilk' - | 'crimson' - | 'darkblue' - | 'darkcyan' - | 'darkgoldenrod' - | 'darkgray' - | 'darkgreen' - | 'darkgrey' - | 'darkkhaki' - | 'darkmagenta' - | 'darkolivegreen' - | 'darkorange' - | 'darkorchid' - | 'darkred' - | 'darksalmon' - | 'darkseagreen' - | 'darkslateblue' - | 'darkslategray' - | 'darkslategrey' - | 'darkturquoise' - | 'darkviolet' - | 'deeppink' - | 'deepskyblue' - | 'dimgray' - | 'dimgrey' - | 'dodgerblue' - | 'firebrick' - | 'floralwhite' - | 'forestgreen' - | 'gainsboro' - | 'ghostwhite' - | 'gold' - | 'goldenrod' - | 'greenyellow' - | 'grey' - | 'honeydew' - | 'hotpink' - | 'indianred' - | 'indigo' - | 'ivory' - | 'khaki' - | 'lavender' - | 'lavenderblush' - | 'lawngreen' - | 'lemonchiffon' - | 'lightblue' - | 'lightcoral' - | 'lightcyan' - | 'lightgoldenrodyellow' - | 'lightgray' - | 'lightgreen' - | 'lightgrey' - | 'lightpink' - | 'lightsalmon' - | 'lightseagreen' - | 'lightskyblue' - | 'lightslategray' - | 'lightslategrey' - | 'lightsteelblue' - | 'lightyellow' - | 'limegreen' - | 'linen' - | 'mediumaquamarine' - | 'mediumblue' - | 'mediumorchid' - | 'mediumpurple' - | 'mediumseagreen' - | 'mediumslateblue' - | 'mediumspringgreen' - | 'mediumturquoise' - | 'mediumvioletred' - | 'midnightblue' - | 'mintcream' - | 'mistyrose' - | 'moccasin' - | 'navajowhite' - | 'oldlace' - | 'olivedrab' - | 'orangered' - | 'orchid' - | 'palegoldenrod' - | 'palegreen' - | 'paleturquoise' - | 'palevioletred' - | 'papayawhip' - | 'peachpuff' - | 'peru' - | 'pink' - | 'plum' - | 'powderblue' - | 'rosybrown' - | 'royalblue' - | 'saddlebrown' - | 'salmon' - | 'sandybrown' - | 'seagreen' - | 'seashell' - | 'sienna' - | 'skyblue' - | 'slateblue' - | 'slategray' - | 'slategrey' - | 'snow' - | 'springgreen' - | 'steelblue' - | 'tan' - | 'thistle' - | 'tomato' - | 'turquoise' - | 'violet' - | 'wheat' - | 'whitesmoke' - | 'yellowgreen' - | 'rebeccapurple'; - -type HexDigit = DecDigit | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'; -type DecDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; -type Digits0to4 = '0' | '1' | '2' | '3' | '4'; - -type WhiteSpace = ' '; -type Trim = T extends `${WhiteSpace}${infer U}` - ? Trim - : T extends `${infer U}${WhiteSpace}` - ? Trim - : T; - -type Hex3 = `${HexDigit}${HexDigit}${HexDigit}`; - -type HexColor = Lowercase extends `#${Hex3}` - ? T - : Lowercase extends `#${Hex3}${infer Rest}` - ? Rest extends Hex3 - ? T - : never - : never; - -type OnlyDecDigits = T extends `${DecDigit}${infer Rest}` - ? Rest extends '' - ? 1 - : OnlyDecDigits - : never; - -type IsDecNumber = T extends `${infer Integer}.${infer Fractional}` - ? Integer extends '' - ? OnlyDecDigits - : Fractional extends '' - ? OnlyDecDigits - : OnlyDecDigits & OnlyDecDigits - : OnlyDecDigits; - -// Necessary for how the type system needs to interpret the value? -// eslint-disable-next-line @typescript-eslint/no-unused-vars -type IntegerPart = T extends `${infer I}.${infer F}` ? I : T; - -type IsInteger = 1 extends IsDecNumber - ? T extends IntegerPart - ? 1 - : never - : never; - -type Less100 = IsDecNumber extends 1 - ? IntegerPart extends `${DecDigit}` | `${DecDigit}${DecDigit}` | '100' - ? 1 - : never - : never; - -type Color255 = 1 extends IsInteger - ? T extends - | `${DecDigit}` - | `${DecDigit}${DecDigit}` - | `1${DecDigit}${DecDigit}` - | `2${Digits0to4}${DecDigit}` - | `25${Digits0to4 | '5'}` - ? 1 - : never - : never; - -type Degree = 1 extends IsInteger - ? T extends - | `${DecDigit}` - | `${DecDigit}${DecDigit}` - | `${'1' | '2'}${DecDigit}${DecDigit}` - | `3${Digits0to4 | '5'}${DecDigit}` - | '360' - ? 1 - : never - : never; - -type IsPercent = '0' extends T ? 1 : T extends `${infer P}%` ? Less100

    : never; - -type IsColorValue = IsPercent | Color255; - -type RGB = T extends `rgb(${infer R},${infer G},${infer B})` - ? '111' extends `${IsColorValue>}${IsColorValue>}${IsColorValue>}` - ? T - : never - : never; - -type Opacity = IsDecNumber | IsPercent; - -type RGBA = T extends `rgba(${infer R},${infer G},${infer B},${infer O})` - ? '1111' extends `${IsColorValue>}${IsColorValue>}${IsColorValue< - Trim - >}${Opacity>}` - ? T - : never - : never; - -type HSL = T extends `hsl(${infer H},${infer S},${infer L})` - ? `111` extends `${Degree>}${IsPercent>}${IsPercent>}` - ? T - : never - : never; - -type HSLA = T extends `hsla(${infer H},${infer S},${infer L},${infer O})` - ? `1111` extends `${Degree>}${IsPercent>}${IsPercent>}${Opacity< - Trim - >}` - ? T - : never - : never; - -type ColorValue = HexColor | RGB | RGBA | HSL | HSLA; - -/** - * A CSS-property compatible color type. Used for properties which will end up - * as a CSS property eventually. - * - * @see https://stackoverflow.com/a/68068969/1309423 - */ -export type Color = - | ColorValue - | ColorKeyword - | 'currentColor' - | 'transparent' - | 'inherit'; diff --git a/test/Documents/BitmapGRF.test.ts b/src/Documents/BitmapGRF.test.ts similarity index 85% rename from test/Documents/BitmapGRF.test.ts rename to src/Documents/BitmapGRF.test.ts index 658c34c..f8bed9d 100644 --- a/test/Documents/BitmapGRF.test.ts +++ b/src/Documents/BitmapGRF.test.ts @@ -1,9 +1,10 @@ -/// +import { expect, describe, it } from 'vitest'; + import { BitmapGRF, DitheringMethod, - ImageConversionOptions -} from '../../src/Documents/BitmapGRF.js'; + type ImageConversionOptions +} from './BitmapGRF.js'; // Class pulled from jest-mock-canvas which I can't seem to actually import. class ImageData { @@ -26,7 +27,24 @@ class ImageData { return 'srgb' as PredefinedColorSpace; } - constructor(arr, w, h) { + + /** + * Creates an `ImageData` object from a given `Uint8ClampedArray` and the size of the image it contains. + * + * @param array A `Uint8ClampedArray` containing the underlying pixel representation of the image. + * @param width An `unsigned` `long` representing the width of the image. + * @param height An `unsigned` `long` representing the height of the image. This value is optional: the height will be inferred from the array's size and the given width. + */ + constructor(array: Uint8ClampedArray, width: number, height?: number) + + /** + * Creates an `ImageData` object of a black rectangle with the given width and height. + * + * @param width An `unsigned` `long` representing the width of the image. + * @param height An `unsigned` `long` representing the height of the image. + */ + constructor(width: number, height: number) + constructor(arr: number | Uint8ClampedArray, w: number, h?: number) { if (arguments.length === 2) { if (arr instanceof Uint8ClampedArray) { if (arr.length === 0) @@ -49,7 +67,7 @@ class ImageData { this._height = height; this._data = new Uint8ClampedArray(width * height * 4); } - } else if (arguments.length === 3) { + } else if (arguments.length === 3 && h !== undefined) { if (!(arr instanceof Uint8ClampedArray)) throw new TypeError('First argument must be a Uint8ClampedArray when using 3 arguments.'); if (arr.length === 0) throw new RangeError('Source length must be a positive multiple of 4.'); @@ -60,7 +78,7 @@ class ImageData { if (!Number.isFinite(w)) throw new RangeError('The width is zero or not a number.'); if (w === 0) throw new RangeError('The width is zero or not a number.'); if (arr.length !== w * h * 4) - throw new RangeError("Source doesn'n contain the exact number of pixels needed."); + throw new RangeError("Source doesn't contain the exact number of pixels needed."); this._width = w; this._height = h; this._data = arr; @@ -74,7 +92,7 @@ global.ImageData = ImageData; function getImageDataInput(width: number, height: number, fill: number, alpha?: number) { const arr = new Uint8ClampedArray(width * height * 4); - if (alpha != null && alpha != fill) { + if (alpha != undefined && alpha != fill) { for (let i = 0; i < arr.length; i += 4) { arr[i + 0] = fill; arr[i + 1] = fill; @@ -112,7 +130,7 @@ describe('RGBA Image Conversion', () => { it('Should downconvert transparent images correctly', () => { const imageData = new ImageData(getImageDataInput(8, 1, 0), 8, 1); const expected = new Uint8Array([(1 << 8) - 1]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -133,7 +151,7 @@ describe('RGBA Image Conversion', () => { it('Should downconvert black images correctly', () => { const imageData = new ImageData(getImageDataInput(8, 1, 0, 255), 8, 1); const expected = new Uint8Array([0]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -154,7 +172,7 @@ describe('RGBA Image Conversion', () => { it('Should downconvert white images correctly', () => { const imageData = new ImageData(getImageDataInput(8, 1, 255), 8, 1); const expected = new Uint8Array([(1 << 8) - 1]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -175,7 +193,7 @@ describe('RGBA Image Conversion', () => { it('Should downconvert checkered images correctly', () => { const imageData = new ImageData(getImageDataInputAlternatingDots(8, 1), 8, 1); const expected = new Uint8Array([85]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -196,7 +214,7 @@ describe('RGBA Image Conversion', () => { it('Should pad and downconvert transparent images correctly', () => { const imageData = new ImageData(getImageDataInput(5, 1, 0), 5, 1); const expected = new Uint8Array([(1 << 8) - 1]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -218,7 +236,7 @@ describe('RGBA Image Conversion', () => { const imgWidth = 4; const imageData = new ImageData(getImageDataInput(imgWidth, 1, 0, 255), imgWidth, 1); const expected = new Uint8Array([(1 << imgWidth) - 1]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -240,7 +258,7 @@ describe('RGBA Image Conversion', () => { const imgWidth = 4; const imageData = new ImageData(getImageDataInput(imgWidth, 1, 255), imgWidth, 1); const expected = new Uint8Array([(1 << 8) - 1]); - const { monochromeData, imageWidth, imageHeight, boundingBox } = BitmapGRF['toMonochrome']( + const { monochromeData, imageWidth, imageHeight } = BitmapGRF['toMonochrome']( imageData.data, imageData.width, imageData.height, @@ -304,14 +322,12 @@ describe('RGBA Round Trip', () => { describe('Whitespace Trimming', () => { it('Should trim to black pixels', () => { // A single black pixel, surrounded by white on all sides, 10 pixels wide. - /* eslint-disable prettier/prettier */ const imageData = new ImageData( new Uint8ClampedArray([ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, ]), 10, 3); - /* eslint-enable prettier/prettier */ const img = BitmapGRF.fromCanvasImageData(imageData, { trimWhitespace: true }); // Width will always be a multiple of 8 due to byte padding. diff --git a/src/Documents/BitmapGRF.ts b/src/Documents/BitmapGRF.ts index 065c385..87ab0bb 100644 --- a/src/Documents/BitmapGRF.ts +++ b/src/Documents/BitmapGRF.ts @@ -1,5 +1,4 @@ -/* eslint-disable prettier/prettier */ -import { Percent } from '../NumericRange.js'; +import type { Percent } from '../NumericRange.js'; import { WebZlpError } from '../WebZlpError.js'; /** Padding information for a trimmed image. */ @@ -21,7 +20,7 @@ export interface ImageBoundingBox { /** Settings for converting an image to a GRF. */ export interface ImageConversionOptions { - /** The threshold brightness below which to consider a pixel black. Defaults to 90. */ + /** The threshold brightness below which to consider a pixel black. Defaults to 70. */ grayThreshold?: Percent; /** Whether to trim whitespace around the image to reduce file size. Trimmed pixels will become padding in the bounding box. */ trimWhitespace?: boolean; @@ -261,7 +260,7 @@ export class BitmapGRF { // // Only supports sRGB as RGBA data. // if (imageData.colorSpace !== 'srgb') { - // throw new DocumentValidationError( + // throw new TranspileDocumentError( // 'Unknown color space for given imageData. Expected srgb but got ' + // imageData.colorSpace // ); @@ -357,17 +356,17 @@ export class BitmapGRF { // https://github.com/metafloor/zpl-image/blob/491f4d6887294d71dcfa859957d43b3be28ce1e5/zpl-image.js // Convert black from percent to 0..255 value - const threshold = (255 * grayThreshold) / 100; + const threshold = (255 * (grayThreshold?? 70)) / 100; // This is where we'd do some dithering, if we implemented anything other than none. - if (ditheringMethod != DitheringMethod.none) { + if (ditheringMethod !== undefined && ditheringMethod !== DitheringMethod.none) { throw new WebZlpError( `Dithering method ${DitheringMethod[ditheringMethod]} is not supported.` ); } let minx: number, maxx: number, miny: number, maxy: number; - if (!trimWhitespace) { + if (trimWhitespace !== true) { minx = miny = 0; maxx = width - 1; maxy = height - 1; diff --git a/src/Documents/Commands.ts b/src/Documents/Commands.ts index f28a4c4..cff652c 100644 --- a/src/Documents/Commands.ts +++ b/src/Documents/Commands.ts @@ -1,573 +1,443 @@ import * as Options from '../Printers/Configuration/PrinterOptions.js'; -import { BitmapGRF, ImageConversionOptions } from './BitmapGRF.js'; +import type { BitmapGRF, ImageConversionOptions } from './BitmapGRF.js'; /** Flags to indicate special operations a command might cause. */ export enum PrinterCommandEffectFlags { - /** No special side-effects outside of what the command does. */ - none = 0, - /** The effects of this command cannot be determined automatically. */ - unknownEffects = 1 << 0, - /** Changes the printer config, necessitating an update of the cached config. */ - altersPrinterConfig = 1 << 1, - /** Causes the printer motor to engage, even if nothing is printed. */ - feedsLabel = 1 << 2, - /** Causes the printer to disconnect or otherwise need reconnecting. */ - lossOfConnection = 1 << 3, - /** Causes something sharp to move */ - actuatesCutter = 1 << 4 + /** No special side-effects outside of what the command does. */ + none = 0, + /** The effects of this command cannot be determined automatically. */ + unknownEffects = 1 << 0, + /** Changes the printer config, necessitating an update of the cached config. */ + altersPrinterConfig = 1 << 1, + /** Causes the printer motor to engage, even if nothing is printed. */ + feedsLabel = 1 << 2, + /** Causes the printer to disconnect or otherwise need reconnecting. */ + lossOfConnection = 1 << 3, + /** Causes something sharp to move */ + actuatesCutter = 1 << 4 } /** A command that can be sent to a printer. */ export interface IPrinterCommand { - /** Get the display name of this command. */ - get name(): string; - /** Get the command type of this command. */ - get type(): CommandType; - - /** Get the human-readable output of this command. */ - toDisplay(): string; - - /** Any effects this command may cause the printer to undergo. */ - readonly printerEffectFlags?: PrinterCommandEffectFlags; + /** Get the display name of this command. */ + readonly name: string; + /** Get the command type of this command. */ + readonly type: CommandType; + /** Any effects this command may cause the printer to undergo. */ + readonly printerEffectFlags: PrinterCommandEffectFlags; + + /** Get the human-readable output of this command. */ + toDisplay(): string; } /** A custom command beyond the standard command set, with command-language-specific behavior. */ export interface IPrinterExtendedCommand extends IPrinterCommand { - /** The unique identifier for this command. */ - get typeExtended(): symbol; + /** The unique identifier for this command. */ + get typeExtended(): symbol; - /** Gets the command languages this extended command can apply to. */ - get commandLanguageApplicability(): Options.PrinterCommandLanguage; + /** Gets the command languages this extended command can apply to. */ + get commandLanguageApplicability(): Options.PrinterCommandLanguage; } /** List of colors to draw elements with */ export enum DrawColor { - /** Draw in black */ - black, - /** Draw in white */ - white + /** Draw in black */ + black, + /** Draw in white */ + white } /** Behavior to take for commands that belong inside or outside of a form. */ export enum CommandReorderBehavior { - /** Perform no reordering, non-form commands will be interpreted as form closing. */ - none = 0, - /** Reorder non-form commands to the end, retaining order. */ - nonFormCommandsAfterForms + /** Perform no reordering, non-form commands will be interpreted as form closing. */ + none = 0, + /** Reorder non-form commands to the end, retaining order. */ + nonFormCommandsAfterForms } -// My kingdom for a real type system, or at least a way to autogenerate this in the -// type system. I have given up on TypeScript actually helping me here. -// TODO: Figure out a way to unit test this to make sure it's complete. -/* eslint-disable prettier/prettier */ -/* eslint-disable @typescript-eslint/naming-convention */ -/** Enum of all possible commands that can be issued. */ -export enum CommandType { - // Some printer commands can be command-language specific. This uses a different lookup table. - CommandLanguageSpecificCommand = 'CommandLanguageSpecificCommand', - // Users may supply printer commands. This uses a different lookup table. - CommandCustomSpecificCommand = 'CommandCustomSpecificCommand', - // Everything else is OOTB commands that should be implemented by internal implmentations. - AddBoxCommand = 'AddBoxCommand', - AddImageCommand = 'AddImageCommand', - AddLineCommand = 'AddLineCommand', - AutosenseLabelDimensionsCommand = 'AutosenseLabelDimensionsCommand', - ClearImageBufferCommand = 'ClearImageBufferCommand', - CutNowCommand = 'CutNowCommand', - EnableFeedBackupCommand = 'EnableFeedBackupCommand', - NewLabelCommand = 'NewLabelCommand', - OffsetCommand = 'OffsetCommand', - PrintCommand = 'PrintCommand', - PrintConfigurationCommand = 'PrintConfigurationCommand', - QueryConfigurationCommand = 'QueryConfigurationCommand', - RawDocumentCommand = 'RawDocumentCommand', - RebootPrinterCommand = 'RebootPrinterCommand', - SaveCurrentConfigurationCommand = 'SaveCurrentConfigurationCommand', - SetDarknessCommand = 'SetDarknessCommand', - SetLabelDimensionsCommand = 'SetLabelDimensionsCommand', - SetLabelHomeCommand = 'SetLabelHomeCommand', - SetLabelPrintOriginOffsetCommand = 'SetLabelPrintOriginOffsetCommand', - SetLabelToContinuousMediaCommand = 'SetLabelToContinuousMediaCommand', - SetLabelToWebGapMediaCommand = 'SetLabelToWebGapMediaCommand', - SetLabelToMarkMediaCommand = 'SetLabelToMarkMediaCommand', - SetPrintDirectionCommand = 'SetPrintDirectionCommand', - SetPrintSpeedCommand = 'SetPrintSpeedCommand', - SuppressFeedBackupCommand = 'SuppressFeedBackupCommand', -} -/* eslint-enable @typescript-eslint/naming-convention */ -/* eslint-enable prettier/prettier */ +/** Union type of all possible commands that must be handled by command sets. */ +export type CommandType + // Users/PCLs may supply printer commands. This uses a different lookup table. + = "CustomCommand" + | "AddBoxCommand" + | "AddImageCommand" + | "AddLineCommand" + | "AutosenseLabelDimensionsCommand" + | "ClearImageBufferCommand" + | "CutNowCommand" + | "EnableFeedBackupCommand" + | "NewLabelCommand" + | "OffsetCommand" + | "PrintCommand" + | "PrintConfigurationCommand" + | "QueryConfigurationCommand" + | "RawDocumentCommand" + | "RebootPrinterCommand" + | "SaveCurrentConfigurationCommand" + | "SetDarknessCommand" + | "SetLabelDimensionsCommand" + | "SetLabelHomeCommand" + | "SetLabelPrintOriginOffsetCommand" + | "SetLabelToContinuousMediaCommand" + | "SetLabelToWebGapMediaCommand" + | "SetLabelToMarkMediaCommand" + | "SetPrintDirectionCommand" + | "SetPrintSpeedCommand" + |"SuppressFeedBackupCommand" export class NewLabelCommand implements IPrinterCommand { - get name(): string { - return 'End previous label and begin a new label.'; - } - get type() { - return CommandType.NewLabelCommand; - } - toDisplay(): string { - return this.name; - } + get name() { return 'End previous label and begin a new label.'; } + get type(): CommandType { return 'NewLabelCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.none; } export class PrintCommand implements IPrinterCommand { - get name(): string { - return 'Print label'; - } - get type() { - return CommandType.PrintCommand; - } - toDisplay(): string { - return `Print ${this.count} copies of label`; - } - - constructor(labelCount = 1, additionalDuplicateOfEach = 1) { - // TODO: If someone complains that this is lower than what ZPL allows - // figure out a way to support the 99,999,999 supported. - // Who needs to print > 65 thousand labels at once??? I want to know. - this.count = labelCount <= 0 || labelCount > 65535 ? 0 : labelCount; - this.additionalDuplicateOfEach = - additionalDuplicateOfEach <= 0 || additionalDuplicateOfEach > 65535 - ? 0 - : additionalDuplicateOfEach; - } - - count: number; - additionalDuplicateOfEach: number; - - printerEffectFlags = PrinterCommandEffectFlags.feedsLabel; + get name() { return 'Print label'; } + get type(): CommandType { return 'PrintCommand'; } + toDisplay(): string { + return `Print ${this.count} copies of label`; + } + + constructor(labelCount = 1, additionalDuplicateOfEach = 1) { + // TODO: If someone complains that this is lower than what ZPL allows + // figure out a way to support the 99,999,999 supported. + // Who needs to print > 65 thousand labels at once??? I want to know. + this.count = labelCount <= 0 || labelCount > 65535 ? 0 : labelCount; + this.additionalDuplicateOfEach = + additionalDuplicateOfEach <= 0 || additionalDuplicateOfEach > 65535 + ? 0 + : additionalDuplicateOfEach; + } + + count: number; + additionalDuplicateOfEach: number; + + printerEffectFlags = PrinterCommandEffectFlags.feedsLabel; } export class CutNowCommand implements IPrinterCommand { - get name(): string { - return 'Cycle the media cutter now'; - } - get type() { - return CommandType.CutNowCommand; - } - toDisplay(): string { - return this.name; - } + get name() { return 'Cycle the media cutter now'; } + get type(): CommandType { return 'CutNowCommand'; } + toDisplay(): string { + return this.name; + } - printerEffectFlags = PrinterCommandEffectFlags.actuatesCutter; + printerEffectFlags = PrinterCommandEffectFlags.actuatesCutter; } export class SuppressFeedBackupCommand implements IPrinterCommand { - get name(): string { - return 'Disable feed backup after printing label (be sure to re-enable!)'; - } - get type() { - return CommandType.SuppressFeedBackupCommand; - } - toDisplay(): string { - return this.name; - } + get name() { return 'Disable feed backup after printing label (be sure to re-enable!)'; } + get type(): CommandType { return 'SuppressFeedBackupCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.none; } export class EnableFeedBackupCommand implements IPrinterCommand { - get name(): string { - return 'Enable feed backup after printing label.'; - } - get type() { - return CommandType.EnableFeedBackupCommand; - } - toDisplay(): string { - return this.name; - } + get name() { return 'Enable feed backup after printing label.'; } + get type(): CommandType { return 'EnableFeedBackupCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.none; } /** A command to clear the image buffer. */ export class ClearImageBufferCommand implements IPrinterCommand { - get name(): string { - return 'Clear image buffer'; - } - get type() { - return CommandType.ClearImageBufferCommand; - } - toDisplay(): string { - return this.name; - } + get name() { return 'Clear image buffer'; } + get type(): CommandType { return 'ClearImageBufferCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.none; } /** A command to have the printer send its configuration back over serial. */ export class QueryConfigurationCommand implements IPrinterCommand { - get name(): string { - return 'Query for printer config'; - } - get type() { - return CommandType.QueryConfigurationCommand; - } - toDisplay(): string { - return this.name; - } + get name() { return 'Query for printer config'; } + get type(): CommandType { return 'QueryConfigurationCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.none; } /** A command to have the printer print its configuration labels. */ export class PrintConfigurationCommand implements IPrinterCommand { - get name(): string { - return "Print printer's config onto labels"; - } - get type() { - return CommandType.PrintConfigurationCommand; - } - toDisplay(): string { - return this.name; - } - printerEffectFlags = PrinterCommandEffectFlags.feedsLabel; + get name() { return "Print printer's config onto labels"; } + get type(): CommandType { return 'PrintConfigurationCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.feedsLabel; } /** A command to store the current configuration as the stored configuration. */ export class SaveCurrentConfigurationCommand implements IPrinterCommand { - get name(): string { - return 'Store the current configuration as the saved configuration.'; - } - get type(): CommandType { - return CommandType.SaveCurrentConfigurationCommand; - } - toDisplay(): string { - return this.name; - } - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + get name() { return 'Store the current configuration as the saved configuration.'; } + get type(): CommandType { return 'SaveCurrentConfigurationCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; } /** A command to set the darkness the printer prints at. */ export class SetDarknessCommand implements IPrinterCommand { - get name(): string { - return 'Set darkness'; - } - get type() { - return CommandType.SetDarknessCommand; - } - toDisplay(): string { - return `Set darkness to ${this.darknessPercent}%`; - } - - constructor(darknessPercent: Options.DarknessPercent, darknessMax: number) { - this.darknessPercent = darknessPercent; - this.darknessMax = darknessMax; - this.darknessSetting = Math.ceil((darknessPercent * darknessMax) / 100); - } - - darknessPercent: Options.DarknessPercent; - darknessMax: number; - darknessSetting: number; - - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + get name() { return 'Set darkness'; } + get type(): CommandType { return 'SetDarknessCommand'; } + toDisplay(): string { + return `Set darkness to ${this.darknessPercent}%`; + } + + constructor( + public readonly darknessPercent: Options.DarknessPercent, + public readonly darknessMax: number + ) {} + + get darknessSetting() { + return Math.ceil((this.darknessPercent * this.darknessMax) / 100); + } + + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; } /** A command to set the direction a label prints, either upside down or not. */ export class SetPrintDirectionCommand implements IPrinterCommand { - get name(): string { - return 'Set print direction'; - } - get type() { - return CommandType.SetPrintDirectionCommand; - } - toDisplay(): string { - return `Print labels ${this.upsideDown ? 'upside-down' : 'right-side up'}`; - } + get name() { return 'Set print direction'; } + get type(): CommandType { return 'SetPrintDirectionCommand'; } + toDisplay(): string { + return `Print labels ${this.upsideDown ? 'upside-down' : 'right-side up'}`; + } - constructor(upsideDown: boolean) { - this.upsideDown = upsideDown; - } + constructor(upsideDown: boolean) { + this.upsideDown = upsideDown; + } - /** Whether to print labels upside-down. */ - upsideDown: boolean; + /** Whether to print labels upside-down. */ + upsideDown: boolean; - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; } /** A command to set the print speed a printer prints at. Support varies per printer. */ export class SetPrintSpeedCommand implements IPrinterCommand { - get name(): string { - return 'Set print speed'; - } - get type() { - return CommandType.SetPrintSpeedCommand; - } - toDisplay(): string { - return `Set print speed to ${Options.PrintSpeed[this.speed]} (inches per second).`; - } - - constructor( - speed: Options.PrintSpeed, - speedVal: number, - mediaSlewSpeed: Options.PrintSpeed, - mediaSpeedVal: number - ) { - this.speed = speed; - this.speedVal = speedVal; - this.mediaSlewSpeed = mediaSlewSpeed; - this.mediaSpeedVal = mediaSpeedVal; - } - - speed: Options.PrintSpeed; - speedVal: number; - mediaSlewSpeed: Options.PrintSpeed; - mediaSpeedVal: number; - - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + get name() { return 'Set print speed'; } + get type(): CommandType { return 'SetPrintSpeedCommand'; } + toDisplay(): string { + return `Set print speed to ${Options.PrintSpeed[this.speed]} (inches per second).`; + } + + constructor( + public readonly speed: Options.PrintSpeed, + public readonly speedVal: number, + public readonly mediaSlewSpeed: Options.PrintSpeed, + public readonly mediaSpeedVal: number + ) { } + + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; } /** A command to set the label dimensions of this label. */ export class SetLabelDimensionsCommand implements IPrinterCommand { - get name(): string { - return 'Set label dimensions'; - } - get type() { - return CommandType.SetLabelDimensionsCommand; - } - toDisplay(): string { - let str = `Set label size to ${this.widthInDots} wide`; - if (this.heightInDots) { - str += ` x ${this.heightInDots} high`; - } - if (this.gapLengthInDots) { - str += ` with a gap length of ${this.gapLengthInDots}`; - } - str += ' (in dots).'; - return str; - } - - get setsHeight() { - return this.heightInDots != null && this.gapLengthInDots != null; - } - - // TODO: Black line mode for EPL? - constructor(widthInDots: number, heightInDots?: number, gapLengthInDots?: number) { - this.widthInDots = widthInDots; - this.heightInDots = heightInDots; - this.gapLengthInDots = gapLengthInDots; - } - - widthInDots: number; - heightInDots?: number; - gapLengthInDots?: number; - - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + get name() { return 'Set label dimensions'; } + get type(): CommandType { return 'SetLabelDimensionsCommand'; } + toDisplay(): string { + let str = `Set label size to ${this.widthInDots} wide`; + if (this.heightInDots) { + str += ` x ${this.heightInDots} high`; + } + if (this.gapLengthInDots) { + str += ` with a gap length of ${this.gapLengthInDots}`; + } + str += ' (in dots).'; + return str; + } + + get setsHeight() { + return this.heightInDots !== undefined && this.gapLengthInDots !== undefined; + } + + // TODO: Black line mode for EPL? + constructor( + public readonly widthInDots: number, + public readonly heightInDots?: number, + public readonly gapLengthInDots?: number) { } + + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; } export class SetLabelHomeCommand implements IPrinterCommand { - get name(): string { - return 'Sets the label home (origin) offset'; - } - get type(): CommandType { - return CommandType.SetLabelHomeCommand; - } - toDisplay(): string { - return `Set the label home (origin) to ${this.xOffset},${this.yOffset} from the top-left.`; - } - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; - - constructor(public xOffset: number, public yOffset: number) {} + get name() { return 'Sets the label home (origin) offset'; } + get type(): CommandType { return 'SetLabelHomeCommand'; } + toDisplay(): string { + return `Set the label home (origin) to ${this.xOffset},${this.yOffset} from the top-left.`; + } + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + + constructor(public xOffset: number, public yOffset: number) { } } /** Command class to set the print offset from the top-left of the label. */ export class SetLabelPrintOriginOffsetCommand implements IPrinterCommand { - get name(): string { - return 'Sets the print offset from the top left corner.'; - } - get type(): CommandType { - return CommandType.SetLabelPrintOriginOffsetCommand; - } - toDisplay(): string { - return `Sets the print offset to ${this.xOffset} in and ${this.yOffset} down from the top-left.`; - } - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; - - constructor(public xOffset: number, public yOffset: number) {} + get name() { return 'Sets the print offset from the top left corner.'; } + get type(): CommandType { return 'SetLabelPrintOriginOffsetCommand'; } + toDisplay(): string { + return `Sets the print offset to ${this.xOffset} in and ${this.yOffset} down from the top-left.`; + } + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + + constructor(public xOffset: number, public yOffset: number) { } } /** A command class to set the media handling mode to continuous media. */ export class SetLabelToContinuousMediaCommand implements IPrinterCommand { - get name(): string { - return 'Sets the media handling mode to continuous media.'; - } - get type(): CommandType { - return CommandType.SetLabelToContinuousMediaCommand; - } - toDisplay(): string { - return this.name; - } - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; - - constructor(public labelLengthInDots: number, public labelGapInDots = 0) {} + get name() { return 'Sets the media handling mode to continuous media.'; } + get type(): CommandType { return 'SetLabelToContinuousMediaCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + + constructor(public labelLengthInDots: number, public labelGapInDots = 0) { } } /** A command class to set the media handling mode to web gap detection. */ export class SetLabelToWebGapMediaCommand implements IPrinterCommand { - get name(): string { - return 'Sets the media handling mode to web gap detection.'; - } - get type(): CommandType { - return CommandType.SetLabelToWebGapMediaCommand; - } - toDisplay(): string { - return this.name; - } - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; - - constructor(public labelLengthInDots: number, public labelGapInDots: number) {} + get name() { return 'Sets the media handling mode to web gap detection.'; } + get type(): CommandType { return 'SetLabelToWebGapMediaCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + + constructor(public labelLengthInDots: number, public labelGapInDots: number) { } } /** A command class to set the media handling mode to black mark detection. */ export class SetLabelToMarkMediaCommand implements IPrinterCommand { - get name(): string { - return 'Sets the media handling mode to black mark detection.'; - } - get type(): CommandType { - return CommandType.SetLabelToMarkMediaCommand; - } - toDisplay(): string { - return this.name; - } - printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; - - constructor( - public labelLengthInDots: number, - public blackLineThicknessInDots: number, - public blackLineOffset: number - ) {} + get name() { return 'Sets the media handling mode to black mark detection.'; } + get type(): CommandType { return 'SetLabelToMarkMediaCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.altersPrinterConfig; + + constructor( + public labelLengthInDots: number, + public blackLineThicknessInDots: number, + public blackLineOffset: number + ) { } } /** Command class to cause the printer to auto-sense the media length. */ export class AutosenseLabelDimensionsCommand implements IPrinterCommand { - get name(): string { - return 'Auto-sense the label length by feeding several labels.'; - } - get type() { - return CommandType.AutosenseLabelDimensionsCommand; - } - toDisplay(): string { - return this.name; - } - - printerEffectFlags = - PrinterCommandEffectFlags.altersPrinterConfig | PrinterCommandEffectFlags.feedsLabel; + get name() { return 'Auto-sense the label length by feeding several labels.'; } + get type(): CommandType { return 'AutosenseLabelDimensionsCommand'; } + toDisplay(): string { + return this.name; + } + + printerEffectFlags = + PrinterCommandEffectFlags.altersPrinterConfig | PrinterCommandEffectFlags.feedsLabel; } /** Command class to modify an offset. */ export class OffsetCommand implements IPrinterCommand { - get name(): string { - return 'Modify offset'; - } - get type() { - return CommandType.OffsetCommand; - } - toDisplay(): string { - let str = `Set offset to ${this.horizontal} from the left`; - if (this.vertical) { - str += ` and ${this.vertical} from the top`; - } - str += this.absolute ? `of the label.` : ` of the current offset.`; - return str; - } - - constructor(horizontal: number, vertical?: number, absolute = false) { - this.horizontal = Math.floor(horizontal); - this.vertical = Math.floor(vertical); - this.absolute = absolute; - } - - horizontal: number; - vertical?: number; - absolute = false; + get name() { return 'Modify offset'; } + get type(): CommandType { return 'OffsetCommand'; } + toDisplay(): string { + let str = `Set offset to ${this.horizontal} from the left`; + if (this.vertical) { + str += ` and ${this.vertical} from the top`; + } + str += this.absolute ? `of the label.` : ` of the current offset.`; + return str; + } + printerEffectFlags = PrinterCommandEffectFlags.none; + + constructor(horizontal: number, vertical?: number, absolute = false) { + this.horizontal = Math.floor(horizontal); + this.vertical = vertical !== undefined ? Math.floor(vertical) : undefined; + this.absolute = absolute; + } + + horizontal: number; + vertical?: number; + absolute = false; } /** Command class to force a printer to reset. */ export class RebootPrinterCommand implements IPrinterCommand { - get name(): string { - return 'Simulate a power-cycle for the printer. This should be the final command.'; - } - get type() { - return CommandType.RebootPrinterCommand; - } - toDisplay(): string { - return this.name; - } - printerEffectFlags = PrinterCommandEffectFlags.lossOfConnection; + get name() { return 'Simulate a power-cycle for the printer. This should be the final command.'; } + get type(): CommandType { return 'RebootPrinterCommand'; } + toDisplay(): string { + return this.name; + } + printerEffectFlags = PrinterCommandEffectFlags.lossOfConnection; } /** Command class to draw an image into the image buffer for immediate print. */ export class AddImageCommand implements IPrinterCommand { - get name(): string { - return 'Add image to label'; - } - get type() { - return CommandType.AddImageCommand; - } - toDisplay(): string { - if (!this.bitmap) { - return 'Adds a blank image'; - } - return `Adds a ${this.bitmap.width} wide x ${this.bitmap.height} high image.`; - } - - constructor(public bitmap: BitmapGRF, public imageConversionOptions: ImageConversionOptions) {} + get name() { return 'Add image to label'; } + get type(): CommandType { return 'AddImageCommand'; } + toDisplay(): string { + if (!this.bitmap) { + return 'Adds a blank image'; + } + return `Adds a ${this.bitmap.width} wide x ${this.bitmap.height} high image.`; + } + printerEffectFlags = PrinterCommandEffectFlags.none; + + constructor( + public bitmap: BitmapGRF, + public imageConversionOptions: ImageConversionOptions + ) { } } /** Command class to draw a straight line. */ export class AddLineCommand implements IPrinterCommand { - get name(): string { - return 'Add perpendicular line to label'; - } - get type() { - return CommandType.AddLineCommand; - } - toDisplay(): string { - // eslint-disable-next-line prettier/prettier - return `Add a ${DrawColor[this.color]} line ${this.lengthInDots} wide by ${this.heightInDots} high.`; - } - - constructor(lengthInDots: number, heightInDots: number, color: DrawColor) { - this.lengthInDots = lengthInDots; - this.heightInDots = heightInDots; - this.color = color; - } - - lengthInDots: number; - heightInDots: number; - color: DrawColor; + get name() { return 'Add perpendicular line to label'; } + get type(): CommandType { return 'AddLineCommand'; } + toDisplay(): string { + return `Add a ${DrawColor[this.color]} line ${this.lengthInDots} wide by ${this.heightInDots} high.`; + } + printerEffectFlags = PrinterCommandEffectFlags.none; + + constructor( + public readonly lengthInDots: number, + public readonly heightInDots: number, + public readonly color: DrawColor + ) { } } /** Command to draw a box on a label */ export class AddBoxCommand implements IPrinterCommand { - get name(): string { - return 'Add a box to label'; - } - get type() { - return CommandType.AddBoxCommand; - } - toDisplay(): string { - return `Add a box ${this.lengthInDots} wide by ${this.heightInDots} high.`; - } - - constructor(lengthInDots: number, heightInDots: number, thickness: number) { - this.lengthInDots = lengthInDots; - this.heightInDots = heightInDots; - this.thickness = thickness; - } - - lengthInDots: number; - heightInDots: number; - thickness: number; + get name() { return 'Add a box to label'; } + get type(): CommandType { return 'AddBoxCommand'; } + toDisplay(): string { + return `Add a box ${this.lengthInDots} wide by ${this.heightInDots} high.`; + } + printerEffectFlags = PrinterCommandEffectFlags.none; + + constructor( + public readonly lengthInDots: number, + public readonly heightInDots: number, + public readonly thickness: number + ) { } } export class RawDocumentCommand implements IPrinterCommand { - get name(): string { - return 'Sends a raw set of commands directly to the printer unmodified.'; - } - get type(): CommandType { - return CommandType.RawDocumentCommand; - } - toDisplay(): string { - throw new Error('Method not implemented.'); - } - printerEffectFlags = PrinterCommandEffectFlags.unknownEffects; - - constructor( - public rawDocument: string, - printerEffectFlags = PrinterCommandEffectFlags.unknownEffects - ) { - this.printerEffectFlags = printerEffectFlags; - } + get name() { return 'Sends a raw set of commands directly to the printer unmodified.'; } + get type(): CommandType { return 'RawDocumentCommand'; } + toDisplay(): string { return this.name; } + + constructor( + public readonly rawDocument: string, + public readonly printerEffectFlags = PrinterCommandEffectFlags.unknownEffects + ) { } } diff --git a/src/Documents/ConfigDocument.ts b/src/Documents/ConfigDocument.ts index 6dc5d37..5981290 100644 --- a/src/Documents/ConfigDocument.ts +++ b/src/Documents/ConfigDocument.ts @@ -1,282 +1,284 @@ import * as Commands from './Commands.js'; -import { IDocument, DocumentBuilder } from './Document.js'; +import { type IDocument, DocumentBuilder } from './Document.js'; import * as Options from '../Printers/Configuration/PrinterOptions.js'; import { WebZlpError } from '../WebZlpError.js'; /** A series of printer commands that results in configuration changes. */ export interface IConfigDocumentBuilder - extends DocumentBuilder, - IPrinterBasicCommandBuilder, - IPrinterConfigBuilder, - IPrinterLabelConfigBuilder {} + extends DocumentBuilder, + IPrinterBasicCommandBuilder, + IPrinterConfigBuilder, + IPrinterLabelConfigBuilder { } /** Builder to generate a configuration to apply to a printer. */ export class ConfigDocumentBuilder - extends DocumentBuilder - implements IConfigDocumentBuilder -{ - get commandReorderBehavior() { - return Commands.CommandReorderBehavior.nonFormCommandsAfterForms; + extends DocumentBuilder + implements IConfigDocumentBuilder { + get commandReorderBehavior() { + return Commands.CommandReorderBehavior.nonFormCommandsAfterForms; + } + + constructor(config?: Options.PrinterOptions) { + super(config ?? Options.PrinterOptions.invalid); + } + + // The config document appends an additional command to the end of the document + // to commit the changes to stored memory. EPL does this automatically, ZPL does not + // so to bring them closer to parity this is automatically implied. + // TODO: Consider whether this should move to a ZPL extended command. + finalize() { + this.andThen(new Commands.SaveCurrentConfigurationCommand()); + return super.finalize(); + } + + ///////////////////// GENERAL LABEL HANDLING + + clearImageBuffer(): IConfigDocumentBuilder { + return this.andThen(new Commands.ClearImageBufferCommand()); + } + + rebootPrinter(): IDocument { + return this.andThen(new Commands.RebootPrinterCommand()).finalize(); + } + + ///////////////////// CONFIG READING + + queryConfiguration(): IConfigDocumentBuilder { + return this.andThen(new Commands.QueryConfigurationCommand()); + } + + printConfiguration(): IDocument { + return this.andThen(new Commands.PrintConfigurationCommand()).finalize(); + } + + ///////////////////// ALTER PRINTER CONFIG + + setDarknessConfig(darknessPercent: Options.DarknessPercent) { + return this.andThen( + new Commands.SetDarknessCommand(darknessPercent, this._config.model.maxDarkness) + ); + } + + setPrintDirection(upsideDown = false) { + return this.andThen(new Commands.SetPrintDirectionCommand(upsideDown)); + } + + setPrintSpeed(speed: Options.PrintSpeed, mediaSlewSpeed = Options.PrintSpeed.ipsAuto) { + if (!this._config.model.isSpeedValid(speed)) { + throw new UnsupportedPrinterConfigError( + 'setPrintSpeed', + `Print speed ${Options.PrintSpeed[speed]} is not valid for model ${this._config.model.model}` + ); } + const speedVal = this._config.model.getSpeedValue(speed); - constructor(config: Options.PrinterOptions) { - super(config); + // If the media slew speed is auto just copy the print speed. + if (mediaSlewSpeed === Options.PrintSpeed.ipsAuto) { + mediaSlewSpeed = speed; } - - // The config document appends an additional command to the end of the document - // to commit the changes to stored memory. EPL does this automatically, ZPL does not - // so to bring them closer to parity this is automatically implied. - // TODO: Consider whether this should move to a ZPL extended command. - finalize() { - this.andThen(new Commands.SaveCurrentConfigurationCommand()); - return super.finalize(); - } - - ///////////////////// GENERAL LABEL HANDLING - - clearImageBuffer(): IConfigDocumentBuilder { - return this.andThen(new Commands.ClearImageBufferCommand()); - } - - rebootPrinter(): IDocument { - return this.andThen(new Commands.RebootPrinterCommand()).finalize(); - } - - ///////////////////// CONFIG READING - - queryConfiguration(): IConfigDocumentBuilder { - return this.andThen(new Commands.QueryConfigurationCommand()); - } - - printConfiguration(): IDocument { - return this.andThen(new Commands.PrintConfigurationCommand()).finalize(); - } - - ///////////////////// ALTER PRINTER CONFIG - - setDarknessConfig(darknessPercent: Options.DarknessPercent) { - return this.andThen( - new Commands.SetDarknessCommand(darknessPercent, this._config.model.maxDarkness) - ); - } - - setPrintDirection(upsideDown = false) { - return this.andThen(new Commands.SetPrintDirectionCommand(upsideDown)); - } - - setPrintSpeed(speed: Options.PrintSpeed, mediaSlewSpeed = Options.PrintSpeed.ipsAuto) { - if (!this._config.model.isSpeedValid(speed)) { - throw new UnsupportedPrinterConfigError( - 'setPrintSpeed', - `Print speed ${Options.PrintSpeed[speed]} is not valid for model ${this._config.model.model}` - ); - } - if (mediaSlewSpeed && !this._config.model.isSpeedValid(mediaSlewSpeed)) { - throw new UnsupportedPrinterConfigError( - 'setPrintSpeed', - `Media slew speed ${Options.PrintSpeed[speed]} is not valid for model ${this._config.model.model}` - ); - } - - // If the media slew speed is auto just copy the print speed. - if (mediaSlewSpeed === Options.PrintSpeed.ipsAuto) { - mediaSlewSpeed = speed; - } - return this.andThen( - new Commands.SetPrintSpeedCommand( - speed, - this._config.model.getSpeedValue(speed), - mediaSlewSpeed, - this._config.model.getSpeedValue(mediaSlewSpeed) - ) - ); - } - - ///////////////////// ALTER LABEL CONFIG - - autosenseLabelLength() { - return this.andThen(new Commands.AutosenseLabelDimensionsCommand()).finalize(); - } - - setLabelDimensions(widthInInches: number, heightInInches?: number, gapLengthInInches?: number) { - const dpi = this._config.model.dpi; - return this.setLabelDimensionsDots( - widthInInches * dpi, - heightInInches ? heightInInches * dpi : null, - gapLengthInInches ? gapLengthInInches * dpi : null - ); - } - - setLabelDimensionsDots(widthInDots: number, heightInDots?: number, gapLengthInDots?: number) { - return this.andThen( - new Commands.SetLabelDimensionsCommand(widthInDots, heightInDots, gapLengthInDots) - ); - } - - setLabelHomeOffsetDots(horizontalOffsetInDots: number, verticalOffsetInDots: number) { - return this.andThen( - new Commands.SetLabelHomeCommand(horizontalOffsetInDots, verticalOffsetInDots) - ); - } - - setLabelPrintOriginOffsetCommand(horizontalOffsetInDots: number, verticalOffsetInDots: number) { - return this.andThen( - new Commands.SetLabelPrintOriginOffsetCommand( - horizontalOffsetInDots, - verticalOffsetInDots - ) - ); - } - - setLabelMediaToContinuous(labelHeightInInches: number): IConfigDocumentBuilder { - const dpi = this._config.model.dpi; - return this.andThen( - new Commands.SetLabelToContinuousMediaCommand(dpi * labelHeightInInches) - ); - } - - setLabelMediaToWebGapSense( - labelHeightInInches: number, - labelGapInInches: number - ): IConfigDocumentBuilder { - const dpi = this._config.model.dpi; - return this.andThen( - new Commands.SetLabelToWebGapMediaCommand( - labelHeightInInches * dpi, - labelGapInInches * dpi - ) - ); - } - - setLabelMediaToMarkSense( - labelLengthInInches: number, - blackLineThicknessInInches: number, - blackLineOffsetInInches: number - ): IConfigDocumentBuilder { - const dpi = this._config.model.dpi; - return this.andThen( - new Commands.SetLabelToMarkMediaCommand( - labelLengthInInches * dpi, - blackLineThicknessInInches * dpi, - blackLineOffsetInInches * dpi - ) - ); + if (mediaSlewSpeed && !this._config.model.isSpeedValid(mediaSlewSpeed)) { + throw new UnsupportedPrinterConfigError( + 'setPrintSpeed', + `Media slew speed ${Options.PrintSpeed[speed]} is not valid for model ${this._config.model.model}` + ); } + const mediaSpeedVal = this._config.model.getSpeedValue(mediaSlewSpeed); + + return this.andThen( + new Commands.SetPrintSpeedCommand( + speed, + speedVal, + mediaSlewSpeed, + mediaSpeedVal, + ) + ); + } + + ///////////////////// ALTER LABEL CONFIG + + autosenseLabelLength() { + return this.andThen(new Commands.AutosenseLabelDimensionsCommand()).finalize(); + } + + setLabelDimensions(widthInInches: number, heightInInches?: number, gapLengthInInches?: number) { + const dpi = this._config.model.dpi; + return this.setLabelDimensionsDots( + widthInInches * dpi, + heightInInches ? heightInInches * dpi : undefined, + gapLengthInInches ? gapLengthInInches * dpi : undefined + ); + } + + setLabelDimensionsDots(widthInDots: number, heightInDots?: number, gapLengthInDots?: number) { + return this.andThen( + new Commands.SetLabelDimensionsCommand(widthInDots, heightInDots, gapLengthInDots) + ); + } + + setLabelHomeOffsetDots(horizontalOffsetInDots: number, verticalOffsetInDots: number) { + return this.andThen( + new Commands.SetLabelHomeCommand(horizontalOffsetInDots, verticalOffsetInDots) + ); + } + + setLabelPrintOriginOffsetCommand(horizontalOffsetInDots: number, verticalOffsetInDots: number) { + return this.andThen( + new Commands.SetLabelPrintOriginOffsetCommand( + horizontalOffsetInDots, + verticalOffsetInDots + ) + ); + } + + setLabelMediaToContinuous(labelHeightInInches: number): IConfigDocumentBuilder { + const dpi = this._config.model.dpi; + return this.andThen( + new Commands.SetLabelToContinuousMediaCommand(dpi * labelHeightInInches) + ); + } + + setLabelMediaToWebGapSense( + labelHeightInInches: number, + labelGapInInches: number + ): IConfigDocumentBuilder { + const dpi = this._config.model.dpi; + return this.andThen( + new Commands.SetLabelToWebGapMediaCommand( + labelHeightInInches * dpi, + labelGapInInches * dpi + ) + ); + } + + setLabelMediaToMarkSense( + labelLengthInInches: number, + blackLineThicknessInInches: number, + blackLineOffsetInInches: number + ): IConfigDocumentBuilder { + const dpi = this._config.model.dpi; + return this.andThen( + new Commands.SetLabelToMarkMediaCommand( + labelLengthInInches * dpi, + blackLineThicknessInInches * dpi, + blackLineOffsetInInches * dpi + ) + ); + } } export interface IPrinterBasicCommandBuilder { - /** Clear the image buffer and prepare for a new set of commands. */ - clearImageBuffer(): IConfigDocumentBuilder; + /** Clear the image buffer and prepare for a new set of commands. */ + clearImageBuffer(): IConfigDocumentBuilder; - /** Simulate turning the printer off and back on. Must be the final command. */ - rebootPrinter(): IDocument; + /** Simulate turning the printer off and back on. Must be the final command. */ + rebootPrinter(): IDocument; } export interface IPrinterConfigBuilder { - /** Query the printer for its config details. */ - queryConfiguration(): IConfigDocumentBuilder; + /** Query the printer for its config details. */ + queryConfiguration(): IConfigDocumentBuilder; - /** Print the configuration directly on labels. Must be final command. */ - printConfiguration(): IDocument; + /** Print the configuration directly on labels. Must be final command. */ + printConfiguration(): IDocument; } export interface IPrinterLabelConfigBuilder { - /** Set the darkness of the printer in the stored configuration. */ - setDarknessConfig(darknessPercent: Options.DarknessPercent): IConfigDocumentBuilder; - - /** Set the direction labels print out of the printer. */ - setPrintDirection(upsideDown?: boolean): IConfigDocumentBuilder; - - /** Set the speed at which the labels print. */ - setPrintSpeed(speed: Options.PrintSpeed): IConfigDocumentBuilder; - - /** - * Set the size of the labels in the printer. - * - * Omit height and gap if an autosense was or will be run. Both must be provided - * to set the length and gap manually, otherwise the length will be ignored. This - * is usually only necessary when using continuous media, see the documentation. - * - * Note that different printers often have slightly different values, copying - * values between printers may have unintended effects. - */ - setLabelDimensions( - widthInInches: number, - heightInInches?: number, - gapLengthInInches?: number - ): IConfigDocumentBuilder; - - /** - * Set the size of the labels in the printer, sized in dots. Dots are printer DPI specific. - * - * Omit height and gap if an autosense was or will be run. Both must be provided - * to set the length and gap manually, otherwise the length will be ignored. This - * is usually only necessary when using continuous media, see the documentation. - * - * Note that different printers often have slightly different values, copying - * values between printers may have unintended effects. - */ - setLabelDimensionsDots( - widthInDots: number, - heightInDots?: number, - gapLengthInDots?: number - ): IConfigDocumentBuilder; - - /** - * Sets the temporary origin offset from the top-left of the label that all - * other offsets are calculated from. Only applies to current label. - * - * Use this to fine-tune the alignment of your printer to your label stock. - * - * Avoid printing off the edges of a label, which can cause excessive head wear. - */ - setLabelHomeOffsetDots( - horizontalOffsetInDots: number, - verticalOffsetInDots: number - ): IConfigDocumentBuilder; - - /** Sets the retained origin offset from the top-left of the label that all - * other offets are calculated from. Applies to all labels until a printer reset - * or power cycle. - * - * May or may not be stored depending on printer firmware. - * - * Avoid printing off the edges of a label, which can cause excessive head wear. - */ - setLabelPrintOriginOffsetCommand( - horizontalOffsetInDots: number, - verticalOffsetInDots: number - ): IConfigDocumentBuilder; - - /** Run the autosense operation to get label length. Must be last command. */ - autosenseLabelLength(): IDocument; - - /** Sets the media type to continuous (gapless) media. */ - setLabelMediaToContinuous(labelLengthInDots: number): IConfigDocumentBuilder; - - /** Sets the media type to web gap sensing media. It's recommended to run autosense after this. */ - setLabelMediaToWebGapSense( - labelLengthInDots: number, - labelGapInDots: number - ): IConfigDocumentBuilder; - - /** Sets the media type to mark sensing media. */ - setLabelMediaToMarkSense( - labelLengthInDots: number, - blackLineThicknessInDots: number, - blackLineOffset: number - ): IConfigDocumentBuilder; + /** Set the darkness of the printer in the stored configuration. */ + setDarknessConfig(darknessPercent: Options.DarknessPercent): IConfigDocumentBuilder; + + /** Set the direction labels print out of the printer. */ + setPrintDirection(upsideDown?: boolean): IConfigDocumentBuilder; + + /** Set the speed at which the labels print. */ + setPrintSpeed(speed: Options.PrintSpeed): IConfigDocumentBuilder; + + /** + * Set the size of the labels in the printer. + * + * Omit height and gap if an autosense was or will be run. Both must be provided + * to set the length and gap manually, otherwise the length will be ignored. This + * is usually only necessary when using continuous media, see the documentation. + * + * Note that different printers often have slightly different values, copying + * values between printers may have unintended effects. + */ + setLabelDimensions( + widthInInches: number, + heightInInches?: number, + gapLengthInInches?: number + ): IConfigDocumentBuilder; + + /** + * Set the size of the labels in the printer, sized in dots. Dots are printer DPI specific. + * + * Omit height and gap if an autosense was or will be run. Both must be provided + * to set the length and gap manually, otherwise the length will be ignored. This + * is usually only necessary when using continuous media, see the documentation. + * + * Note that different printers often have slightly different values, copying + * values between printers may have unintended effects. + */ + setLabelDimensionsDots( + widthInDots: number, + heightInDots?: number, + gapLengthInDots?: number + ): IConfigDocumentBuilder; + + /** + * Sets the temporary origin offset from the top-left of the label that all + * other offsets are calculated from. Only applies to current label. + * + * Use this to fine-tune the alignment of your printer to your label stock. + * + * Avoid printing off the edges of a label, which can cause excessive head wear. + */ + setLabelHomeOffsetDots( + horizontalOffsetInDots: number, + verticalOffsetInDots: number + ): IConfigDocumentBuilder; + + /** Sets the retained origin offset from the top-left of the label that all + * other offets are calculated from. Applies to all labels until a printer reset + * or power cycle. + * + * May or may not be stored depending on printer firmware. + * + * Avoid printing off the edges of a label, which can cause excessive head wear. + */ + setLabelPrintOriginOffsetCommand( + horizontalOffsetInDots: number, + verticalOffsetInDots: number + ): IConfigDocumentBuilder; + + /** Run the autosense operation to get label length. Must be last command. */ + autosenseLabelLength(): IDocument; + + /** Sets the media type to continuous (gapless) media. */ + setLabelMediaToContinuous(labelLengthInDots: number): IConfigDocumentBuilder; + + /** Sets the media type to web gap sensing media. It's recommended to run autosense after this. */ + setLabelMediaToWebGapSense( + labelLengthInDots: number, + labelGapInDots: number + ): IConfigDocumentBuilder; + + /** Sets the media type to mark sensing media. */ + setLabelMediaToMarkSense( + labelLengthInDots: number, + blackLineThicknessInDots: number, + blackLineOffset: number + ): IConfigDocumentBuilder; } /** Error indicating setting a config value failed. */ export class UnsupportedPrinterConfigError extends WebZlpError { - constructor(settingName: string, settingError: string) { - super(`Error setting ${settingName}: ${settingError}`); - this.name = this.constructor.name; - this.settingName = settingName; - this.settingError = settingError; - } - - settingName: string; - settingError: string; + constructor(settingName: string, settingError: string) { + super(`Error setting ${settingName}: ${settingError}`); + this.name = this.constructor.name; + this.settingName = settingName; + this.settingError = settingError; + } + + settingName: string; + settingError: string; } diff --git a/src/Documents/Document.ts b/src/Documents/Document.ts index e958f38..abcd146 100644 --- a/src/Documents/Document.ts +++ b/src/Documents/Document.ts @@ -3,80 +3,80 @@ import * as Options from '../Printers/Configuration/PrinterOptions.js'; /** A prepared document, ready to be compiled and sent. */ export interface IDocument { - /** Gets the series of commands this document contains. */ - get commands(): ReadonlyArray; + /** Gets the series of commands this document contains. */ + get commands(): ReadonlyArray; - /** Gets the behavior allowed for reordering commands in this document. */ - get commandReorderBehavior(): Commands.CommandReorderBehavior; + /** Gets the behavior allowed for reordering commands in this document. */ + get commandReorderBehavior(): Commands.CommandReorderBehavior; - /** Return the list of commands that will be performed in human-readable format. */ - showCommands(): string; + /** Return the list of commands that will be performed in human-readable format. */ + showCommands(): string; } export class Document implements IDocument { - constructor( - public readonly commands: ReadonlyArray, - public readonly commandReorderBehavior = Commands.CommandReorderBehavior.none - ) {} + constructor( + public readonly commands: ReadonlyArray, + public readonly commandReorderBehavior = Commands.CommandReorderBehavior.none + ) { } - /** Display the commands that will be performed in a human-readable format. */ - public showCommands(): string { - return this.commands.map((c) => c.toDisplay()).join('\n'); - } + /** Display the commands that will be performed in a human-readable format. */ + public showCommands(): string { + return this.commands.map((c) => c.toDisplay()).join('\n'); + } } /** A document of raw commands, ready to be sent to a printer. */ export class CompiledDocument { - constructor( - public readonly commandLanguage: Options.PrinterCommandLanguage, - public readonly effectFlags: Commands.PrinterCommandEffectFlags, - public readonly commandBuffer: Uint8Array - ) {} + constructor( + public readonly commandLanguage: Options.PrinterCommandLanguage, + public readonly effectFlags: Commands.PrinterCommandEffectFlags, + public readonly commandBuffer: Uint8Array + ) { } - /** - * Gets the text view of the command buffer. Do not send this to the printer, the encoding - * will break and commands will fail. - */ - get commandBufferString(): string { - return new TextDecoder('ascii').decode(this.commandBuffer); - } + /** + * Gets the text view of the command buffer. Do not send this to the printer, the encoding + * will break and commands will fail. + */ + get commandBufferString(): string { + return new TextDecoder('ascii').decode(this.commandBuffer); + } } /** A basic document builder, containing internal state to construct a document. */ export abstract class DocumentBuilder> { - private _commands: Commands.IPrinterCommand[] = []; - protected _config: Options.PrinterOptions; + private _commands: Commands.IPrinterCommand[] = []; + protected _config: Options.PrinterOptions; - /** The reordering behavior for commands that should not be present within a document. */ - abstract get commandReorderBehavior(): Commands.CommandReorderBehavior; + /** The reordering behavior for commands that should not be present within a document. */ + abstract get commandReorderBehavior(): Commands.CommandReorderBehavior; - constructor(config: Options.PrinterOptions) { - this._config = config; - } + constructor(config: Options.PrinterOptions) { + this._config = config; + } - /** Gets a read-only copy of the current label configuration. */ - get currentConfig() { - return structuredClone(this._config); - } + /** Gets a read-only copy of the current label configuration. */ + get currentConfig() { + return structuredClone(this._config); + } - /** Clear the commands in this document and reset it to the starting blank. */ - clear(): TBuilder { - this._commands = []; - return this as unknown as TBuilder; - } + /** Clear the commands in this document and reset it to the starting blank. */ + clear(): TBuilder { + this._commands = []; + return this as unknown as TBuilder; + } - /** Return the list of commands that will be performed in human-readable format. */ - showCommands(): string { - return this._commands.map((c) => c.toDisplay()).join('\n'); - } + /** Return the list of commands that will be performed in human-readable format. */ + showCommands(): string { + return this._commands.map((c) => c.toDisplay()).join('\n'); + } - /** Return the final built document. */ - finalize(): Document { - return new Document(this._commands, this.commandReorderBehavior); - } + /** Return the final built document. */ + finalize(): Document { + return new Document(this._commands, this.commandReorderBehavior); + } - protected andThen(command: Commands.IPrinterCommand): TBuilder { - this._commands.push(command); - return this as unknown as TBuilder; - } + protected andThen(...command: Commands.IPrinterCommand[]): TBuilder { + this._commands.push(...command); + return this as unknown as TBuilder; + } } diff --git a/src/Documents/LabelDocument.ts b/src/Documents/LabelDocument.ts index f35dff7..b8a2525 100644 --- a/src/Documents/LabelDocument.ts +++ b/src/Documents/LabelDocument.ts @@ -1,215 +1,212 @@ import * as Commands from './Commands.js'; import { DocumentBuilder } from './Document.js'; import * as Options from '../Printers/Configuration/PrinterOptions.js'; -import { BitmapGRF, ImageConversionOptions } from './BitmapGRF.js'; +import { BitmapGRF, type ImageConversionOptions } from './BitmapGRF.js'; export interface ILabelDocumentBuilder - extends DocumentBuilder, - ILabelActionCommandBuilder, - ILabelPositionCommandBuilder, - ILabelContentCommandBuilder {} + extends DocumentBuilder, + ILabelActionCommandBuilder, + ILabelPositionCommandBuilder, + ILabelContentCommandBuilder { } export class LabelDocumentBuilder - extends DocumentBuilder - implements ILabelDocumentBuilder -{ + extends DocumentBuilder + implements ILabelDocumentBuilder { + + get commandReorderBehavior(): Commands.CommandReorderBehavior { + return Commands.CommandReorderBehavior.none; + } + + constructor( + config?: Options.PrinterOptions, // TOOD: Implement other document types, such as stored forms, with type safety // so that only certain commands can be used on them. // Maybe different types?? - private _docType: LabelDocumentType = LabelDocumentType.instanceForm; - - get commandReorderBehavior(): Commands.CommandReorderBehavior { - return Commands.CommandReorderBehavior.none; - } - - constructor( - config: Options.PrinterOptions, - docType: LabelDocumentType = LabelDocumentType.instanceForm - ) { - super(config); - this._docType = docType; - } - - ///////////////////// GENERAL LABEL HANDLING - - clearImageBuffer(): ILabelDocumentBuilder { - return this.andThen(new Commands.ClearImageBufferCommand()); - } - - addPrintCmd(count?: number, additionalDuplicateOfEach?: number): ILabelDocumentBuilder { - return this.andThen(new Commands.PrintCommand(count ?? 1, additionalDuplicateOfEach ?? 0)); - } - - addCutNowCommand(): ILabelDocumentBuilder { - return this.andThen(new Commands.CutNowCommand()); - } - - startNewLabel(): ILabelDocumentBuilder { - return this.andThen(new Commands.NewLabelCommand()); - } - - suppressFeedBackupForLabel(): ILabelDocumentBuilder { - return this.andThen(new Commands.SuppressFeedBackupCommand()); - } - - reenableFeedBackup(): ILabelDocumentBuilder { - return this.andThen(new Commands.EnableFeedBackupCommand()); - } - - ///////////////////// OFFSET AND SPACING - - setOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder { - return this.andThen(new Commands.OffsetCommand(horizontal, vertical, true)); - } - - setLabelHomeOffsetDots(horizontalOffsetInDots: number, verticalOffsetInDots: number) { - return this.andThen( - new Commands.SetLabelHomeCommand(horizontalOffsetInDots, verticalOffsetInDots) - ); - } - - addOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder { - return this.andThen(new Commands.OffsetCommand(horizontal, vertical)); - } - - resetOffset(): ILabelDocumentBuilder { - return this.andThen(new Commands.OffsetCommand(0, 0, true)); - } - - ///////////////////// LABEL IMAGE CONTENTS - - addImageFromImageData( - imageData: ImageData, - imageConversionOptions: ImageConversionOptions = {} - ): ILabelDocumentBuilder { - return this.andThen( - new Commands.AddImageCommand( - BitmapGRF.fromCanvasImageData(imageData), - imageConversionOptions - ) - ); - } - - addImageFromGRF( - image: BitmapGRF, - imageConversionOptions: ImageConversionOptions = {} - ): ILabelDocumentBuilder { - return this.andThen(new Commands.AddImageCommand(image, imageConversionOptions)); - } - - async addImageFromSVG( - svg: string, - widthInDots: number, - heightInDots: number, - imageConversionOptions: ImageConversionOptions = {} - ): Promise { - const img = await BitmapGRF.fromSVG(svg, widthInDots, heightInDots, imageConversionOptions); - const result = this.addImageFromGRF(img, imageConversionOptions); - return result; - } - - addLine(lengthInDots: number, heightInDots: number, color = Commands.DrawColor.black) { - return this.andThen(new Commands.AddLineCommand(lengthInDots, heightInDots, color)); - } - - addBox( - lengthInDots: number, - heightInDots: number, - thicknessInDots: number - ): ILabelDocumentBuilder { - return this.andThen( - new Commands.AddBoxCommand(lengthInDots, heightInDots, thicknessInDots) - ); - } + public readonly docType: LabelDocumentType = LabelDocumentType.instanceForm + ) { + super(config ?? Options.PrinterOptions.invalid); + } + + ///////////////////// GENERAL LABEL HANDLING + + clearImageBuffer(): ILabelDocumentBuilder { + return this.andThen(new Commands.ClearImageBufferCommand()); + } + + addPrintCmd(count?: number, additionalDuplicateOfEach?: number): ILabelDocumentBuilder { + return this.andThen(new Commands.PrintCommand(count ?? 1, additionalDuplicateOfEach ?? 0)); + } + + addCutNowCommand(): ILabelDocumentBuilder { + return this.andThen(new Commands.CutNowCommand()); + } + + startNewLabel(): ILabelDocumentBuilder { + return this.andThen(new Commands.NewLabelCommand()); + } + + suppressFeedBackupForLabel(): ILabelDocumentBuilder { + return this.andThen(new Commands.SuppressFeedBackupCommand()); + } + + reenableFeedBackup(): ILabelDocumentBuilder { + return this.andThen(new Commands.EnableFeedBackupCommand()); + } + + ///////////////////// OFFSET AND SPACING + + setOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder { + return this.andThen(new Commands.OffsetCommand(horizontal, vertical, true)); + } + + setLabelHomeOffsetDots(horizontalOffsetInDots: number, verticalOffsetInDots: number) { + return this.andThen( + new Commands.SetLabelHomeCommand(horizontalOffsetInDots, verticalOffsetInDots) + ); + } + + addOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder { + return this.andThen(new Commands.OffsetCommand(horizontal, vertical)); + } + + resetOffset(): ILabelDocumentBuilder { + return this.andThen(new Commands.OffsetCommand(0, 0, true)); + } + + ///////////////////// LABEL IMAGE CONTENTS + + addImageFromImageData( + imageData: ImageData, + imageConversionOptions: ImageConversionOptions = {} + ): ILabelDocumentBuilder { + return this.andThen( + new Commands.AddImageCommand( + BitmapGRF.fromCanvasImageData(imageData), + imageConversionOptions + ) + ); + } + + addImageFromGRF( + image: BitmapGRF, + imageConversionOptions: ImageConversionOptions = {} + ): ILabelDocumentBuilder { + return this.andThen(new Commands.AddImageCommand(image, imageConversionOptions)); + } + + async addImageFromSVG( + svg: string, + widthInDots: number, + heightInDots: number, + imageConversionOptions: ImageConversionOptions = {} + ): Promise { + const img = await BitmapGRF.fromSVG(svg, widthInDots, heightInDots, imageConversionOptions); + const result = this.addImageFromGRF(img, imageConversionOptions); + return result; + } + + addLine(lengthInDots: number, heightInDots: number, color = Commands.DrawColor.black) { + return this.andThen(new Commands.AddLineCommand(lengthInDots, heightInDots, color)); + } + + addBox( + lengthInDots: number, + heightInDots: number, + thicknessInDots: number + ): ILabelDocumentBuilder { + return this.andThen( + new Commands.AddBoxCommand(lengthInDots, heightInDots, thicknessInDots) + ); + } } /** Types of label documents to send to printers. See the docs. */ export enum LabelDocumentType { - /** A form that is only used for one set of commands, then discarded. */ - instanceForm, - /** A form that is stored in the printer to be re-used. */ - storedForm, - /** A form that is rendered as an image before being sent to the printer. */ - imageForm + /** A form that is only used for one set of commands, then discarded. */ + instanceForm, + /** A form that is stored in the printer to be re-used. */ + storedForm, + /** A form that is rendered as an image before being sent to the printer. */ + imageForm } export interface ILabelActionCommandBuilder { - /** Add a commant to print a number of the preceding label instructions. Defaults to 1 */ - addPrintCmd(count?: number, additionalDuplicateOfEach?: number): ILabelDocumentBuilder; + /** Add a commant to print a number of the preceding label instructions. Defaults to 1 */ + addPrintCmd(count?: number, additionalDuplicateOfEach?: number): ILabelDocumentBuilder; - /** Clear the image buffer to prepare for a new label. Usually only at the start of a label. */ - clearImageBuffer(): ILabelDocumentBuilder; + /** Clear the image buffer to prepare for a new label. Usually only at the start of a label. */ + clearImageBuffer(): ILabelDocumentBuilder; - /** Add a command to cut a label, usually at the end of a label and right before the print command. */ - addCutNowCommand(): ILabelDocumentBuilder; + /** Add a command to cut a label, usually at the end of a label and right before the print command. */ + addCutNowCommand(): ILabelDocumentBuilder; - /** Begin a new label to be sent as a single batch. */ - startNewLabel(): ILabelDocumentBuilder; + /** Begin a new label to be sent as a single batch. */ + startNewLabel(): ILabelDocumentBuilder; - /** Disable feed backup for this label. Be sure to re-enable at the end of the batch. */ - suppressFeedBackupForLabel(): ILabelDocumentBuilder; + /** Disable feed backup for this label. Be sure to re-enable at the end of the batch. */ + suppressFeedBackupForLabel(): ILabelDocumentBuilder; - /** Re-enable feed backup for this and future labels. */ - reenableFeedBackup(): ILabelDocumentBuilder; + /** Re-enable feed backup for this and future labels. */ + reenableFeedBackup(): ILabelDocumentBuilder; } export interface ILabelPositionCommandBuilder { - /** Set the aboslute offset from the top left position of the label. - * - * Avoid printing off the edges of a label, which can cause excessive head wear. - */ - setOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder; - - /** - * Sets the temporary origin offset from the top-left of the label that all - * other offsets are calculated from. Only applies to current label. - * - * Avoid printing off the edges of a label, which can cause excessive head wear. - */ - setLabelHomeOffsetDots( - horizontalOffsetInDots: number, - verticalOffsetInDots: number - ): ILabelDocumentBuilder; - - /** Add a relative offset to the current offset from the top left position of the label. - * - * Avoid printing off the edges of a label, which can cause excessive head wear. - */ - addOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder; - - /** Resets the offset back to origin (top left of label) */ - resetOffset(): ILabelDocumentBuilder; + /** Set the aboslute offset from the top left position of the label. + * + * Avoid printing off the edges of a label, which can cause excessive head wear. + */ + setOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder; + + /** + * Sets the temporary origin offset from the top-left of the label that all + * other offsets are calculated from. Only applies to current label. + * + * Avoid printing off the edges of a label, which can cause excessive head wear. + */ + setLabelHomeOffsetDots( + horizontalOffsetInDots: number, + verticalOffsetInDots: number + ): ILabelDocumentBuilder; + + /** Add a relative offset to the current offset from the top left position of the label. + * + * Avoid printing off the edges of a label, which can cause excessive head wear. + */ + addOffset(horizontal: number, vertical?: number): ILabelDocumentBuilder; + + /** Resets the offset back to origin (top left of label) */ + resetOffset(): ILabelDocumentBuilder; } export interface ILabelContentCommandBuilder { - /** Add an ImageData object as an image to the label */ - addImageFromImageData( - imageData: ImageData, - imageConversionOptions?: ImageConversionOptions - ): ILabelDocumentBuilder; - - /** Add a bitmap GRF image to the label */ - addImageFromGRF(image: BitmapGRF): ILabelDocumentBuilder; - - /** Add an SVG image to the label, rendered to the given width and height. */ - addImageFromSVG( - svg: string, - widthInDots: number, - heightInDots: number, - imageConversionOptions?: ImageConversionOptions - ): Promise; - - /** Draw a line from the current offset for the length and height. */ - addLine( - lengthInDots: number, - heightInDots: number, - color?: Commands.DrawColor - ): ILabelDocumentBuilder; - - /** Draw a box from the current offset. */ - addBox( - lengthInDots: number, - heightInDots: number, - thicknessInDots: number - ): ILabelDocumentBuilder; + /** Add an ImageData object as an image to the label */ + addImageFromImageData( + imageData: ImageData, + imageConversionOptions?: ImageConversionOptions + ): ILabelDocumentBuilder; + + /** Add a bitmap GRF image to the label */ + addImageFromGRF(image: BitmapGRF): ILabelDocumentBuilder; + + /** Add an SVG image to the label, rendered to the given width and height. */ + addImageFromSVG( + svg: string, + widthInDots: number, + heightInDots: number, + imageConversionOptions?: ImageConversionOptions + ): Promise; + + /** Draw a line from the current offset for the length and height. */ + addLine( + lengthInDots: number, + heightInDots: number, + color?: Commands.DrawColor + ): ILabelDocumentBuilder; + + /** Draw a box from the current offset. */ + addBox( + lengthInDots: number, + heightInDots: number, + thicknessInDots: number + ): ILabelDocumentBuilder; } diff --git a/src/Documents/ReadyToPrintDocuments.ts b/src/Documents/ReadyToPrintDocuments.ts index eb60588..53b04a2 100644 --- a/src/Documents/ReadyToPrintDocuments.ts +++ b/src/Documents/ReadyToPrintDocuments.ts @@ -1,96 +1,94 @@ import { ConfigDocumentBuilder } from '../Documents/ConfigDocument.js'; import { LabelDocumentBuilder } from '../Documents/LabelDocument.js'; -import { Printer } from '../Printers/Printer.js'; -import { DarknessPercent, PrintSpeed } from '../Printers/Configuration/PrinterOptions.js'; +import { LabelPrinter } from '../Printers/Printer.js'; +import { type DarknessPercent, PrintSpeed } from '../Printers/Configuration/PrinterOptions.js'; /** Collection of handy documents ready to go. */ export class ReadyToPrintDocuments { - private static readonly printerGetConfigDoc = new ConfigDocumentBuilder(null) - .queryConfiguration() - .finalize(); - /** A command document to query the printer for configuration. */ - static get configDocument() { - return this.printerGetConfigDoc; - } + private static readonly printerGetConfigDoc = new ConfigDocumentBuilder() + .queryConfiguration() + .finalize(); + /** A command document to query the printer for configuration. */ + static get configDocument() { + return this.printerGetConfigDoc; + } - /* eslint-disable prettier/prettier */ - private static readonly printerPrintConfigDoc = new ConfigDocumentBuilder(null) - .printConfiguration(); - /* eslint-enable prettier/prettier */ - /** A command document to make the printer print its configuration. */ - static get printConfigDocument() { - return this.printerPrintConfigDoc; - } + private static readonly printerPrintConfigDoc = new ConfigDocumentBuilder() + .printConfiguration(); + /** A command document to make the printer print its configuration. */ + static get printConfigDocument() { + return this.printerPrintConfigDoc; + } - private static readonly feedLabelDoc = new LabelDocumentBuilder(null).addPrintCmd(1).finalize(); - /** A label document to feed a single label. */ - static get feedLabelDocument() { - return this.feedLabelDoc; - } + private static readonly feedLabelDoc = new LabelDocumentBuilder().addPrintCmd(1).finalize(); + /** A label document to feed a single label. */ + static get feedLabelDocument() { + return this.feedLabelDoc; + } - /** - * Print a test pattern that looks like - * - * ████████████ - * - * ███ - * ███ - * ███ - * ███ - * - * //////////// - * - * Needs to know the width to adjust the pattern. - */ - static printTestLabelDocument(labelWidthInDots: number) { - const label = new LabelDocumentBuilder(null); - const labelWidth = labelWidthInDots; - const quarter = labelWidth / 4; - const lineHeight = 20; + /** + * Print a test pattern that looks like + * + * ████████████ + * + * ███ + * ███ + * ███ + * ███ + * + * //////////// + * + * Needs to know the width to adjust the pattern. + */ + static printTestLabelDocument(labelWidthInDots: number) { + const label = new LabelDocumentBuilder(); + const labelWidth = labelWidthInDots; + const quarter = labelWidth / 4; + const lineHeight = 20; - // Blocks - label - .resetOffset() - .addLine(labelWidth, lineHeight * 2) - .setOffset(0, lineHeight * 2) - .addLine(quarter, lineHeight) - .setOffset(quarter, lineHeight * 3) - .addLine(quarter, lineHeight) - .setOffset(quarter * 2, lineHeight * 4) - .addLine(quarter, lineHeight) - .setOffset(quarter * 3, lineHeight * 5) - .addLine(quarter, lineHeight) - .setOffset(0, lineHeight * 6); + // Blocks + label + .resetOffset() + .addLine(labelWidth, lineHeight * 2) + .setOffset(0, lineHeight * 2) + .addLine(quarter, lineHeight) + .setOffset(quarter, lineHeight * 3) + .addLine(quarter, lineHeight) + .setOffset(quarter * 2, lineHeight * 4) + .addLine(quarter, lineHeight) + .setOffset(quarter * 3, lineHeight * 5) + .addLine(quarter, lineHeight) + .setOffset(0, lineHeight * 6); - // Lines - const slashStart = lineHeight * 6 + 5; - const slashHeight = 8; - for (let i = 0; i <= labelWidth; i += 4) { - label - .setOffset(i + 0, slashStart + 0) - .addLine(1, slashHeight) - .setOffset(i + 1, slashStart + slashHeight) - .addLine(1, slashHeight) - .setOffset(i + 2, slashStart + slashHeight * 2) - .addLine(1, slashHeight) - .setOffset(i + 3, slashStart + slashHeight * 3) - .addLine(1, slashHeight); - } - return label.addPrintCmd().finalize(); + // Lines + const slashStart = lineHeight * 6 + 5; + const slashHeight = 8; + for (let i = 0; i <= labelWidth; i += 4) { + label + .setOffset(i + 0, slashStart + 0) + .addLine(1, slashHeight) + .setOffset(i + 1, slashStart + slashHeight) + .addLine(1, slashHeight) + .setOffset(i + 2, slashStart + slashHeight * 2) + .addLine(1, slashHeight) + .setOffset(i + 3, slashStart + slashHeight * 3) + .addLine(1, slashHeight); } + return label.addPrintCmd().finalize(); + } - /** Combine the common label settings into one config document. */ - static configLabelSettings( - printer: Printer, - labelWidthInches: number, - darknessPercent: DarknessPercent - ) { - return printer - .getConfigDocument() - .setPrintDirection() - .setPrintSpeed(PrintSpeed.ipsAuto) - .setDarknessConfig(darknessPercent) - .setLabelDimensions(labelWidthInches) - .autosenseLabelLength(); - } + /** Combine the common label settings into one config document. */ + static configLabelSettings( + printer: LabelPrinter, + labelWidthInches: number, + darknessPercent: DarknessPercent + ) { + return printer + .getConfigDocument() + .setPrintDirection() + .setPrintSpeed(PrintSpeed.ipsAuto) + .setDarknessConfig(darknessPercent) + .setLabelDimensions(labelWidthInches) + .autosenseLabelLength(); + } } diff --git a/src/Documents/index.ts b/src/Documents/index.ts new file mode 100644 index 0000000..933c9e2 --- /dev/null +++ b/src/Documents/index.ts @@ -0,0 +1,6 @@ +export * from './BitmapGRF.js' +export * from './Commands.js' +export * from './ConfigDocument.js' +export * from './Document.js' +export * from './LabelDocument.js' +export * from './ReadyToPrintDocuments.js' diff --git a/src/NumericRange.test.ts b/src/NumericRange.test.ts new file mode 100644 index 0000000..aae0272 --- /dev/null +++ b/src/NumericRange.test.ts @@ -0,0 +1,16 @@ +import { test, expect, describe } from 'vitest'; +import { clampToRange } from './NumericRange.js'; + +describe("clampToRange tests", () => { + test('high number is clamped down', () => { + expect(clampToRange(5, 0, 2)).toBe(2); + }); + + test('low number is clamped up', () => { + expect(clampToRange(-1, 0, 5)).toBe(0); + }); + + test('in-range number is not modified', () => { + expect(clampToRange(3, 0, 5)).toBe(3); + }); +}); diff --git a/src/NumericRange.ts b/src/NumericRange.ts index a3a06f7..1232b23 100644 --- a/src/NumericRange.ts +++ b/src/NumericRange.ts @@ -5,3 +5,30 @@ type Enumerate = Acc['length'] exte export type NumericRange = Exclude, Enumerate>; export type Percent = NumericRange<0, 101>; + +/** Clamp a number to a given range of values. */ +export function clampToRange(value: number, min: number, max: number) { + return Math.min(Math.max(value, min), max); +} + +/** Return a number if it's within an inclusive range, otherwise return the default. */ +export function numberInRange( + str: string, + min?: number, + max?: number) { + if (!/^\d+$/.test(str)) { + return; + } + const val = Number(str); + if (min !== undefined && val < min) { + return; + } + if (max !== undefined && val > max) { + return; + } + return val; +} + +export function repeat(val: T, count: number) { + return new Array(count).fill(val) as T[]; +} diff --git a/src/PrinterUsbManager.ts b/src/PrinterUsbManager.ts index b4af721..be26112 100644 --- a/src/PrinterUsbManager.ts +++ b/src/PrinterUsbManager.ts @@ -1,130 +1,187 @@ -/// -import { Printer } from './Printers/Printer.js'; -import { PrinterCommunicationOptions } from './Printers/PrinterCommunicationOptions.js'; +import type { IDevice, IDeviceCommunicationOptions, IDeviceEvent } from './Printers/Communication/DeviceCommunication.js'; -export interface PrinterManagerEventMap { - connectedPrinter: CustomEvent<{ detail: Printer }>; - disconnectedPrinter: CustomEvent<{ detail: Printer }>; +export interface IUsbDeviceManagerEventMap { + connectedDevice: CustomEvent>; + disconnectedDevice: CustomEvent>; } -/** Singleton for handling USB printer management. +export interface IUsbDeviceCommunicationOptions extends IDeviceCommunicationOptions { + /** Connection options for what types of USB devices to pay attention to. */ + requestOptions: USBDeviceRequestOptions; +} + +type DeviceGetter = ( + device: USBDevice, + deviceCommunicationOptions: IUsbDeviceCommunicationOptions +) => TDevice; + +/** Singleton for handling USB device management. * * This class can be used to handle the WebUSB communication management for you instead of handling - * printer communication yourself. The promptToConnect method is used to prompt the user to select - * a printer using the browser's UI. Once paired at least once the browser will rember and reconnect + * device connections yourself. The promptToConnect method is used to prompt the user to select + * a device using the browser's UI. Once paired at least once the browser will remember and reconnect * automatically. * * This class exposes events, which your code should add handlers for: - * * connectedPrinter: Fired when a printer is ready to be interacted with. - * * disconnectedPrinter: Fired when a printer is no longer connected. + * * connectedDevice: Fired when a device is ready to be interacted with. + * * disconnectedDevice: Fired when a device is no longer connected. * - * This class will bind to WebUSB events on the Navigator element, your code should ensure only - * one instance is ever instantiated to avoid conflicts. + * This class will attempt to manage any USB devices that match the filter you + * provide in the constructor. If you instantiate it multiple times you must use + * different USBDeviceFilters, otherwise managers will start managing each other's + * devices. This will very likely lead to unintended operation. */ -export class PrinterUsbManager extends EventTarget { - private nav: Navigator; +export class UsbDeviceManager extends EventTarget { + private usb: USB; - /** List of tracked printers. */ - private _printers: Printer[] = []; - public get printers(): readonly Printer[] { - return this._printers; - } - /** Corresponding list of tracked devices */ - private devices: USBDevice[] = []; - // TODO: Switch to Record since we use this for a reverse mapping. + /** Map of tracked devices to their wrapper objects. */ + private _devices = new Map(); + public get devices() { return [...this._devices.values()]; } + + private deviceGetter: DeviceGetter; + + /** Communication behavior when communicating with devices. */ + public deviceCommunicationOptions: IUsbDeviceCommunicationOptions; + + constructor( + navigatorUsb: USB, + deviceConstructor: DeviceGetter, + commOpts?: IUsbDeviceCommunicationOptions + ) { + super(); + this.usb = navigatorUsb; + this.deviceGetter = deviceConstructor; + this.deviceCommunicationOptions = commOpts ?? { + debug: true, + requestOptions: { + filters: [{ + vendorId: 0x0a5f // Zebra + }] + } + }; - /** Default comm options used when connecting to a printer. */ - public printerCommunicationOptions: PrinterCommunicationOptions; + this.usb.addEventListener('connect', this.handleConnect.bind(this)); + this.usb.addEventListener('disconnect', this.handleDisconnect.bind(this)); + } - constructor(nav: Navigator, printerCommOpts?: PrinterCommunicationOptions) { - super(); - this.nav = nav; - this.printerCommunicationOptions = printerCommOpts ?? new PrinterCommunicationOptions(); + public addEventListener>( + type: T, + listener: EventListenerObject | null | ((this: UsbDeviceManager, ev: IUsbDeviceManagerEventMap[T]) => void), + options?: boolean | AddEventListenerOptions + ): void; + public addEventListener( + type: string, + callback: EventListenerOrEventListenerObject | null, + options?: boolean | AddEventListenerOptions + ): void { + super.addEventListener(type, callback, options); + } - // Since this was created assume control over USB. - this.nav.usb.addEventListener('connect', this.handleConnectPrinter.bind(this)); - this.nav.usb.addEventListener('disconnect', this.handleDisconnectPrinter.bind(this)); + /** Ask the user to connect to a device, using the filter from deviceCommunicationOptions. */ + public async promptForNewDevice(): Promise { + try { + const device = await this.usb.requestDevice(this.deviceCommunicationOptions.requestOptions); + await this.handleConnect(new USBConnectionEvent('connect', { device })); + } catch (e) { + // User cancelled + if ( + e instanceof DOMException && + e.name === 'NotFoundError' && + e.message.endsWith('No device selected.') + ) { + return false; + } + throw e; } + return true; + } - public addEventListener( - type: T, - listener: (this: PrinterUsbManager, ev: PrinterManagerEventMap[T]) => void, - options?: boolean | AddEventListenerOptions - ): void; - public addEventListener( - type: string, - callback: EventListenerOrEventListenerObject, - options?: boolean | AddEventListenerOptions - ): void { - super.addEventListener(type, callback, options); + /** Disconnect then reconnect all devices */ + public async forceReconnect() { + const oldList = Array.from(this._devices.values()); + this._devices.clear(); + await Promise.all([...oldList].map(async (value) => value.dispose())); + + const newDevices = await this.usb.getDevices(); + await Promise.all( + newDevices + .map((d) => new USBConnectionEvent('connect', { device: d })) + .map(async (e) => await this.handleConnect(e)) + ); + } + + /** Handler for device connection events. */ + public async handleConnect({ device }: USBConnectionEvent): Promise { + // Make sure it's a device this manager cares about. + if (!this.isManageableDevice(device)) { + // Whatever device this is it isn't one we'd be able to ask the user to + // connect to. We shouldn't attempt to talk to it. + return; } - /** Display the USB device connection dialog to select a printer. */ - public async promptToConnectUsbPrinter(options?: USBDeviceRequestOptions) { - try { - const device = await this.nav.usb.requestDevice( - options ?? { - filters: [ - { - vendorId: 0x0a5f // Zebra - } - ] - } - ); - await this.handleConnectPrinter({ device }); - } catch (e) { - if ( - e instanceof DOMException && - e.name === 'NotFoundError' && - e.message === 'No device selected.' - ) { - return; - } - throw e; - } + // Only handle registration if we aren't already tracking a device + let dev = this._devices.get(device) + if (dev === undefined) { + dev = this.deviceGetter(device, this.deviceCommunicationOptions); + this._devices.set(device, dev); } - /** Simulate all printers being disconnected and reconnected. */ - public async reconnectAllPrinters() { - this.devices = []; - await Promise.all(this._printers.map(async (p) => await p.dispose())); - this._printers = []; + // Don't notify that the device exists until it's ready to exist. + await dev.ready; - const devices = await navigator.usb.getDevices(); - await Promise.all( - devices.map(async (device) => await this.handleConnectPrinter({ device })) - ); + this.sendEvent('connectedDevice', { device: dev }); + } + + /** Handler for device disconnection events. */ + public async handleDisconnect({ device }: USBConnectionEvent): Promise { + const dev = this._devices.get(device); + if (dev === undefined) { + return; } + this._devices.delete(device); + await dev.dispose(); + + this.sendEvent('disconnectedDevice', { device: dev }); + } - /** Handler for printer connection events. */ - public async handleConnectPrinter({ device }): Promise { - // Reconnection events may fire for known printers, exclude them. - if (this.devices.includes(device)) { - return; - } - this.devices.push(device); - const printer = Printer.fromUSBDevice(device, this.printerCommunicationOptions); - this._printers.push(printer); - - // Don't notify that the printer exists until it's ready to exist. - await printer.ready; - - const event = new CustomEvent('connectedPrinter', { detail: printer }); - this.dispatchEvent(event); + private sendEvent( + eventName: keyof IUsbDeviceManagerEventMap, + detail: IDeviceEvent + ): boolean { + return super.dispatchEvent(new CustomEvent>(eventName, { detail })); + } + + /** Determine if a given device is allowed to be managed by this manager. */ + private isManageableDevice(device: USBDevice): boolean { + const filters = this.deviceCommunicationOptions.requestOptions.filters; + const exclusionFilters = this.deviceCommunicationOptions.requestOptions.exclusionFilters ?? []; + + // Step 1: Look for filters where the device doesn't match. + const shouldBeFiltered = filters.map(filter => { + return (filter.vendorId !== undefined && filter.vendorId !== device.vendorId) + || (filter.productId !== undefined && filter.productId !== device.productId) + || (filter.classCode !== undefined && filter.classCode !== device.deviceClass) + || (filter.subclassCode !== undefined && filter.subclassCode !== device.deviceSubclass) + || (filter.protocolCode !== undefined && filter.protocolCode !== device.deviceProtocol) + || (filter.serialNumber !== undefined && filter.serialNumber !== device.serialNumber); + }); + if (shouldBeFiltered.some(r => r === true)) { + return false; } - /** Handler for printer disconnection events. */ - public async handleDisconnectPrinter({ device }): Promise { - const idx = this.devices.findIndex((i) => i == device); - if (idx < 0) { - return; - } - const printer = this._printers[idx]; - this.devices.splice(idx, 1); - this._printers.splice(idx, 1); - await printer.dispose(); - - const event = new CustomEvent('disconnectedPrinter', { detail: printer }); - this.dispatchEvent(event); + // Step 2: Look for exclusions where the device does match. + const shouldBeExcluded = exclusionFilters.map(filter => { + return (filter.vendorId !== undefined && filter.vendorId === device.vendorId) + || (filter.productId !== undefined && filter.productId === device.productId) + || (filter.classCode !== undefined && filter.classCode === device.deviceClass) + || (filter.subclassCode !== undefined && filter.subclassCode === device.deviceSubclass) + || (filter.protocolCode !== undefined && filter.protocolCode === device.deviceProtocol) + || (filter.serialNumber !== undefined && filter.serialNumber === device.serialNumber); + }); + if (shouldBeExcluded.some(r => r === true)) { + return false; } + + return true; + } } diff --git a/src/Printers/Communication/DeviceCommunication.ts b/src/Printers/Communication/DeviceCommunication.ts new file mode 100644 index 0000000..7cf576c --- /dev/null +++ b/src/Printers/Communication/DeviceCommunication.ts @@ -0,0 +1,92 @@ +import { WebZlpError } from "../../WebZlpError.js"; + +/** Possible ways to communicate with a device */ +export type DeviceChannelType + = "USB" + | "Serial" + | "Bluetooth" + | "Network" + +/** Whether data can be transmitted or received from the device. */ +export enum ConnectionDirectionMode { + none, + unidirectional, + bidirectional +} + +export interface IDeviceCommunicationOptions { + /** Whether to display printer communication to the dev console. */ + debug: boolean; + + /** Milliseconds to wait for messages from a device before assuming it's done talking. Defaults to 500ms. */ + messageWaitTimeoutMS?: number +} + +export interface IDevice { + /** Close the connection to this device and clean up unmanaged resources. */ + dispose(): Promise; + + /** Whether the device is connected. */ + get connected(): boolean; + + /** A promise indicating this device is ready to be used. */ + ready: Promise; +} + +export interface IDeviceEvent { + device: TDevice; +} + +/** Static metadata for a connected device. */ +export interface IDeviceInformation { + readonly manufacturerName?: string | undefined; + readonly productName?: string | undefined; + readonly serialNumber?: string | undefined; +} + +/** A communication channel for talking to a device. */ +export interface IDeviceChannel { + /** Gets the mode the communication is set up as. */ + get commMode(): ConnectionDirectionMode; + + /** Gets this channel type. */ + readonly channelType: DeviceChannelType; + + /** A promise indicating this communication channel is ready for use. */ + get ready(): Promise; + + /** Whether the device is connected. */ + get connected(): boolean; + + /** Close the channel, disallowing future communication. */ + dispose(): Promise; + + /** Gets the basic information for the device connected on this channel. */ + getDeviceInfo(): IDeviceInformation + + /** + * Send a series of commands to the device. + * @param commandBuffer The series of commands to send in order. + */ + sendCommands(commandBuffer: TOutput): Promise; + + /** Request data from the device. */ + getInput(): Promise; +} + +/** Error indicating communication with the device has failed. */ +export class DeviceCommunicationError extends WebZlpError { + constructor(message?: string, innerException?: Error) { + super(message ?? innerException?.message ?? 'Error communicating with device'); + this.innerException = innerException; + } + + innerException?: Error; +} + +/** Error indicating the device was not ready to communicate */ +export class DeviceNotReadyError extends DeviceCommunicationError { + constructor(message?: string, innerException?: Error) { + super(message ?? innerException?.message ?? 'Device not ready to communicate.'); + } +} diff --git a/src/Printers/Communication/LineBreakTransformer.ts b/src/Printers/Communication/LineBreakTransformer.ts index f47418f..8ea3ecd 100644 --- a/src/Printers/Communication/LineBreakTransformer.ts +++ b/src/Printers/Communication/LineBreakTransformer.ts @@ -1,14 +1,14 @@ export class LineBreakTransformer implements Transformer { - private container = ''; + private container = ''; - transform(chunk: string, controller: TransformStreamDefaultController) { - this.container += chunk; - const lines = this.container.split('\n'); - this.container = lines.pop(); - lines.forEach((line) => controller.enqueue(line)); - } + transform(chunk: string, controller: TransformStreamDefaultController) { + this.container += chunk; + const lines = this.container.split('\n'); + this.container = lines.pop() ?? ''; + lines.forEach((line) => controller.enqueue(line)); + } - flush(controller: TransformStreamDefaultController) { - controller.enqueue(this.container); - } + flush(controller: TransformStreamDefaultController) { + controller.enqueue(this.container); + } } diff --git a/src/Printers/Communication/PrinterCommunication.ts b/src/Printers/Communication/PrinterCommunication.ts deleted file mode 100644 index f876210..0000000 --- a/src/Printers/Communication/PrinterCommunication.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { WebZlpError } from '../../WebZlpError.js'; -/** A communication channel for talking to a printer device. */ -export interface IPrinterDeviceChannel { - /** Whether to print communications to the console. */ - enableConsoleDebug: boolean; - - /** Gets the mode the communication is set up as. */ - get commMode(): PrinterCommMode; - - /** Gets this channel mode. */ - get channelMode(): PrinterChannelType; - - /** Gets the printer model hint, if available. Used to detect config faster. */ - get modelHint(): string; - - /** A promise indicating this communication channel is ready for use. */ - get ready(): Promise; - - /** Gets the stream for receiving data from this printer. */ - get streamFromPrinter(): ReadableStream; - - /** Close the channel, disallowing future communication. */ - dispose(): Promise; - - /** - * Send a series of commands to the printer. - * @param commandBuffer The series of commands to execute in order. - */ - sendCommands(commandBuffer: Uint8Array): Promise; -} - -/** Error indicating communication with the printer has failed. */ -export class PrinterCommunicationError extends WebZlpError { - constructor(message?: string, innerException?: Error) { - super(message ?? innerException.message); - this.innerException = innerException; - } - - innerException: Error; -} - -/** Possible ways to communicate with a printer */ -export enum PrinterChannelType { - /** Printer is connected to the local machine via USB. */ - usb, - /** Printer is connected to the local machine via Serial. */ - serial, - /** Printer is connected to the local machine via Bluetooth. */ - bluetooth, - /** Printer is available on the network. */ - network -} - -export enum PrinterCommMode { - none, - unidirectional, - bidirectional -} diff --git a/src/Printers/Communication/UsbPrinterDeviceChannel.ts b/src/Printers/Communication/UsbPrinterDeviceChannel.ts index 7e59a60..0d25af8 100644 --- a/src/Printers/Communication/UsbPrinterDeviceChannel.ts +++ b/src/Printers/Communication/UsbPrinterDeviceChannel.ts @@ -1,213 +1,307 @@ import { WebZlpError } from '../../WebZlpError.js'; +import { ConnectionDirectionMode, DeviceCommunicationError, DeviceNotReadyError, type IDeviceChannel, type IDeviceCommunicationOptions, type IDeviceInformation } from './DeviceCommunication.js'; import { LineBreakTransformer } from './LineBreakTransformer.js'; -import { - PrinterChannelType, - IPrinterDeviceChannel, - PrinterCommMode, - PrinterCommunicationError -} from './PrinterCommunication.js'; + +export interface IUSBDeviceInformation extends IDeviceInformation { + readonly deviceClass: number; + readonly deviceSubclass: number; + readonly deviceProtocol: number; + readonly vendorId: number; + readonly productId: number; + readonly deviceVersionMajor: number; + readonly deviceVersionMinor: number; + readonly deviceVersionSubminor: number; +} + +function deviceToInfo(device: USBDevice): IUSBDeviceInformation { + return { + deviceClass: device.deviceClass, + deviceProtocol: device.deviceProtocol, + deviceSubclass: device.deviceSubclass, + deviceVersionMajor: device.deviceVersionMajor, + deviceVersionMinor: device.deviceVersionMinor, + deviceVersionSubminor: device.deviceVersionSubminor, + productId: device.productId, + vendorId: device.vendorId, + manufacturerName: device.manufacturerName, + productName: device.productName, + serialNumber: device.serialNumber, + }; +} /** Class for managing the WebUSB communication with a printer. */ -export class UsbPrinterDeviceChannel extends EventTarget implements IPrinterDeviceChannel { - private device: USBDevice; - private deviceIn: USBEndpoint; - private deviceOut: USBEndpoint; +export class UsbDeviceChannel implements IDeviceChannel { + private device: USBDevice; + private deviceIn?: USBEndpoint; + private deviceOut?: USBEndpoint; + + private _commOptions: IDeviceCommunicationOptions; + + public readonly channelType = "USB" as const; + + private _commMode = ConnectionDirectionMode.none; + public get commMode() { return this._commMode; } + + private _readyFlag = false; + private _readyPromise: Promise; + public get ready() { return this._readyPromise; } + public get connected() { + return !this._disposed + && this._readyFlag + && this.device.opened + } + + private _disposed = false; + + private _inputStream?: ReadableStream; - public enableConsoleDebug = false; + constructor( + device: USBDevice, + commOptions: IDeviceCommunicationOptions = { debug: false } + ) { + this.device = device; + this._commOptions = commOptions; + this._readyPromise = this.setup(); + } - private _commMode: PrinterCommMode; - public get commMode() { - return this._commMode; + private async setup() { + try { + await this.connect(); + } catch { + await this.dispose(); } + this._readyFlag = true; + return true; + } - get channelMode(): PrinterChannelType { - return PrinterChannelType.usb; + public async dispose() { + if (this._disposed) { + return; } - private _ready: Promise; - public get ready(): Promise { - return this._ready; + this._disposed = true; + this._readyPromise = Promise.resolve(false); + try { + await this.device.close(); + } catch (e) { + if ( + e instanceof DOMException && + e.name === 'NotFoundError' && + e.message === + "Failed to execute 'close' on 'USBDevice': The device was disconnected." + ) { + // Device was already closed, no-op. + return; + } + + throw e; } + } - private inputStream: ReadableStream; - public get streamFromPrinter() { - return this.inputStream; + public async sendCommands( + commandBuffer: Uint8Array + ): Promise { + if (this.deviceOut === undefined || !this.connected) { + return new DeviceNotReadyError(); } - public get modelHint(): string { - return this.device?.productName; + if (this._commOptions.debug) { + console.debug('Sending command buffer to device via USB.'); + console.time('commandBufferSendTime'); } - constructor(device: USBDevice, enableConsoleDebug = false) { - super(); + try { + // TOOD: Add timeout in case of communication hang. + await this.device.transferOut(this.deviceOut.endpointNumber, commandBuffer); + return; + } catch (e: unknown) { + if (typeof e === 'string') { + return new DeviceCommunicationError(e); + } + if (e instanceof Error) { + return new DeviceCommunicationError(undefined, e); + } + // Dunno what this is but we can't wrap it. + throw e; + } finally { + if (this._commOptions.debug) { + console.timeEnd('commandBufferSendTime'); + console.debug('Completed sending commands.'); + } + } + } - this.device = device; - this.enableConsoleDebug = enableConsoleDebug; + private async connect() { + const d = this.device; - this._ready = this.setup(); + // Most devices have two endpoints on one interface for bidirectional bulk + // in and out. The more poorly performing a device the more random this + // layout will be, so we must go and look for these two endpoints. + if (d.configurations[0]?.interfaces[0]?.alternates[0] === undefined) { + // Can't talk to the device at all??? + throw new DeviceCommunicationError( + 'USB device did not expose an endpoint to communicate with. Try power-cycling the device, or checking its settings. This is a hardware problem.' + ); } - private async setup() { - await this.connect(); - return true; + // Open the connections! Stop having it be closed! + try { + await d.open(); + } catch (e) { + if ( + e instanceof DOMException && + e.name === 'SecurityError' && + e.message === "Failed to execute 'open' on 'USBDevice': Access denied." + ) { + // This can happen if something else, usually the operating system, has taken + // exclusive access of the USB device and won't allow WebUSB to take control. + // This most often happens on Windows. You can use Zadig to replace the driver. + throw new DriverAccessDeniedError(); + } + + throw e; } - public async dispose() { - try { - await this.device.close(); - } catch (e) { - if ( - e instanceof DOMException && - e.name === 'NotFoundError' && - e.message === - "Failed to execute 'close' on 'USBDevice': The device was disconnected." - ) { - // Device was already closed, no-op. - return; - } + await d.selectConfiguration(1); + await d.claimInterface(0); - throw e; - } + // A standard Zebra printer will have two endpoints on one interface. + // One of them will be output, one of them will be input. They can be + // in a random order (or missing!) so we must enumerate them to find them. + let o: USBEndpoint | undefined = undefined; + let i: USBEndpoint | undefined = undefined; + for (const endpoint of d.configurations[0].interfaces[0].alternates[0].endpoints) { + if (endpoint.direction == 'out') { + o = endpoint; + } else if (endpoint.direction == 'in') { + i = endpoint; + } } - public async sendCommands( - commandBuffer: Uint8Array - ): Promise { - if (this.enableConsoleDebug) { - console.debug('Sending print command buffer to printer via USB..'); - console.time('sendPrintBuffer'); - } - - try { - // TOOD: Add timeout in case of communication hang. - await this.device.transferOut(this.deviceOut.endpointNumber, commandBuffer); - return null; - } catch (e: unknown) { - if (typeof e === 'string') { - return new PrinterCommunicationError(e); - } - if (e instanceof Error) { - return new PrinterCommunicationError(null, e); - } - // Dunno what this is but we can't wrap it. - throw e; - } finally { - if (this.enableConsoleDebug) { - console.timeEnd('sendPrintBuffer'); - console.debug('Completed sending print command.'); - } - } + // For no apparent reason sometimes printers will omit to advertise the + // input endpoint. Sometimes they'll also omit the output endpoint. This + // attempts to handle those situations in a degraded mode. + if (!o) { + throw new WebZlpError( + 'USB printer did not expose an output endpoint. Try power-cycling the printer. This is a hardware problem.' + ); + } else { + this.deviceOut = o; } - private async connect() { - const d = this.device; + if (!i) { + console.warn('USB printer did not expose an input endpoint, using unidirectinal mode.'); + } else { + this.deviceIn = i; + } - // Any sane USB device should expose at least one configuration with one - // interface. - if ( - d.configurations.length === 0 || - d.configurations[0].interfaces.length === 0 || - d.configurations[0].interfaces[0].alternates.length === 0 - ) { - throw new WebZlpError('USB printer did not expose any USB interfaces. Try power-cycling the printer. This is a hardware problem.'); - } + this._commMode = this.getCommMode(this.deviceOut !== undefined, this.deviceIn !== undefined); + if (this._commMode === ConnectionDirectionMode.none) { + // Can't talk to the printer so don't try. + return; + } - // A standard Zebra printer will have two endpoints on one interface. - // One of them will be output, one of them will be input. They can be - // in a random order (or missing!) so we must enumerate them to find them. - let o: USBEndpoint, i: USBEndpoint; - for (const endpoint of d.configurations[0].interfaces[0].alternates[0].endpoints) { - if (endpoint.direction == 'out') { - o = endpoint; - } else if (endpoint.direction == 'in') { - i = endpoint; - } - } + if (this._commOptions.debug) { + console.debug('Comm mode with printer is', ConnectionDirectionMode[this._commMode]); + } - // For no apparent reason sometimes printers will omit to advertise the - // input endpoint. Sometimes they'll also omit the output endpoint. This - // attempts to handle those situations in a degraded mode. - if (!o) { - throw new WebZlpError( - 'USB printer did not expose an output endpoint. Try power-cycling the printer. This is a hardware problem.' + // Can only read if there's an endpoint to read from, otherwise skip. + if (this._commMode === ConnectionDirectionMode.bidirectional) { + this._inputStream = new ReadableStream({ + pull: async (controller) => { + if (this.deviceIn === undefined || !this.device.opened) { + return undefined; + } + const result = await this.device.transferIn(this.deviceIn.endpointNumber, 64); + if (result.data !== undefined) { + const chunk = new Uint8Array( + result.data.buffer, + result.data.byteOffset, + result.data.byteLength ); - } else { - this.deviceOut = o; + controller.enqueue(chunk); + } } + }) + .pipeThrough(new TextDecoderStream()) + .pipeThrough(new TransformStream(new LineBreakTransformer())); + } + } - if (!i) { - console.warn('USB printer did not expose an input endpoint, using unidirectinal mode.'); - } else { - this.deviceIn = i; - } + public getDeviceInfo() { + return deviceToInfo(this.device); + } - this._commMode = this.getCommMode(this.deviceOut != null, this.deviceIn != null); - if (this._commMode === PrinterCommMode.none) { - // Can't talk to the printer so don't try. - return; - } + public async getInput(): Promise { + if (!this.connected || this.deviceIn === undefined) { + return new DeviceNotReadyError('Channel is not connected.'); + } - if (this.enableConsoleDebug) { - console.debug('Comm mode with printer is', PrinterCommMode[this._commMode]); - } + let aggregate = ''; + for (; ;) { + const line = await this.nextLine(this._commOptions.messageWaitTimeoutMS ?? 500); + if (line === undefined) { + this.logIfDebug(`Received ${aggregate.length} long message from printer:\n`, aggregate); + return [aggregate]; + } + aggregate += line + '\n'; + } + } - // Open the connections! Stop having it be closed! - try { - await d.open(); - } catch (e) { - if ( - e instanceof DOMException && - e.name === 'SecurityError' && - e.message === "Failed to execute 'open' on 'USBDevice': Access denied." - ) { - // This can happen if something else, usually the operating system, has taken - // exclusive access of the USB device and won't allow WebUSB to take control. - // This most often happens on Windows. You can use Zadig to replace the driver. - throw new DriverAccessDeniedError(); - } - - throw e; - } + /** Wait for the next line of data sent from the printer, or an empty string if nothing is received. */ + private async nextLine(timeoutMs: number): Promise { + if (this._inputStream === undefined) { return; } + let reader: ReadableStreamDefaultReader; + const nextLinePromise = (async () => { + if (this._inputStream === undefined) { return; } - await d.selectConfiguration(1); - await d.claimInterface(0); - - // Can only read if there's an endpoint to read from, otherwise skip. - if (this._commMode === PrinterCommMode.bidirectional) { - this.inputStream = new ReadableStream({ - pull: async (controller) => { - const result = await this.device.transferIn(this.deviceIn.endpointNumber, 64); - const chunk = new Uint8Array( - result.data.buffer, - result.data.byteOffset, - result.data.byteLength - ); - controller.enqueue(chunk); - } - }) - .pipeThrough(new TextDecoderStream()) - .pipeThrough(new TransformStream(new LineBreakTransformer())); - } + reader = this._inputStream.getReader(); + const { value, done } = await reader.read(); + reader.releaseLock(); + + if (done) { + return; + } + + return value; + })(); + + const timeoutPromise = new Promise((resolve) => { + setTimeout(() => { + reader.releaseLock(); + resolve(); + }, timeoutMs); + }); + + return Promise.race([nextLinePromise, timeoutPromise]); + } + + private getCommMode(output: boolean, input: boolean) { + // TODO: Figure out if getting the Interface Protocol Mode is more + // reliable than the detection method used here... + if (output === false) { + // Can't talk to something that isn't listening... + return ConnectionDirectionMode.none; } + if (input === false) { + // Can send commands but can't get info back. Operating in the blind. + return ConnectionDirectionMode.unidirectional; + } + return ConnectionDirectionMode.bidirectional; + } - private getCommMode(output: boolean, input: boolean) { - if (output === false) { - // No output means we can't control the printer at all. - return PrinterCommMode.none; - } - if (input === false) { - // No input means we can't listen for feedback, but can send commands. - return PrinterCommMode.unidirectional; - } - return PrinterCommMode.bidirectional; + private logIfDebug(...obj: unknown[]) { + if (this._commOptions.debug) { + console.debug(...obj); } + } } /** Error indicating the printer's driver cannot be used by WebUSB. */ export class DriverAccessDeniedError extends WebZlpError { - constructor() { - super( - 'Operating system prevented accessing the USB device. If this is on Windows you may need to replace the driver. See https://cellivar.github.io/WebZLP/docs/windows_driver for more details.' - ); - } + constructor() { + super( + 'Operating system prevented accessing the USB device. If this is on Windows you may need to replace the driver. See https://cellivar.github.io/WebZLP/docs/windows_driver for more details.' + ); + } } diff --git a/src/Printers/Configuration/MediaOptions.ts b/src/Printers/Configuration/MediaOptions.ts index f4cda9c..3710b98 100644 --- a/src/Printers/Configuration/MediaOptions.ts +++ b/src/Printers/Configuration/MediaOptions.ts @@ -1,192 +1,207 @@ -import { Percent } from '../../NumericRange.js'; +import type { Percent } from '../../NumericRange.js'; /** The darkness of the printer setting, higher being printing darker. */ export type DarknessPercent = Percent; /** Printer options related to the label media being printed */ export interface IPrinterLabelMediaOptions { - /** How dark to print. 0 is blank, 99 is max darkness */ - darknessPercent: DarknessPercent; - /** Mode the printer uses to detect separate labels when printing. */ - labelGapDetectMode: LabelMediaGapDetectionMode; - /** - * The gap / mark length between labels. Mandatory for markSensing black line mode. - * Media with webSensing gaps can use AutoSense to get this value. - */ - get labelGapInches(): number; - /** Label gap in dots */ - labelGapDots: number; - /** The offset in inches from the normal location of the label gap or black line. Can be negative. */ - get labelLineOffsetInches(): number; - /** The offset in dots from the normal location of the label gap or black line. Can be negative. */ - labelLineOffsetDots: number; - /** The height of the label media, in inches. */ - get labelHeightInches(): number; - /** The height of the label media, in dots. */ - labelHeightDots: number; - /** The width of the label media, in inches. */ - get labelWidthInches(): number; - /** The width of the label media, in dots. */ - labelWidthDots: number; - - /** The offset of the printable area, from the top-left corner. */ - labelPrintOriginOffsetDots: Coordinate; - - /** Label print speed settings */ - speed: PrintSpeedSettings; - - /** The label media thermal print mode. */ - thermalPrintMode: ThermalPrintMode; - - /** The behavior of media after form printing. */ - mediaPrintMode: MediaPrintMode; - - /** Whether the label prints right-side-up or upside-down. */ - printOrientation: PrintOrientation; + /** How dark to print. 0 is blank, 99 is max darkness */ + darknessPercent: DarknessPercent; + /** Mode the printer uses to detect separate labels when printing. */ + labelGapDetectMode: LabelMediaGapDetectionMode; + /** + * The gap / mark length between labels. Mandatory for markSensing black line mode. + * Media with webSensing gaps can use AutoSense to get this value. + */ + get labelGapInches(): number; + /** Label gap in dots */ + labelGapDots: number; + /** The offset in inches from the normal location of the label gap or black line. Can be negative. */ + get labelLineOffsetInches(): number; + /** The offset in dots from the normal location of the label gap or black line. Can be negative. */ + labelLineOffsetDots: number; + /** The height of the label media, in inches. */ + get labelHeightInches(): number; + /** The height of the label media, in dots. */ + labelHeightDots: number; + /** The width of the label media, in inches. */ + get labelWidthInches(): number; + /** The width of the label media, in dots. */ + labelWidthDots: number; + + /** The offset of the printable area, from the top-left corner. */ + labelPrintOriginOffsetDots: Coordinate; + + /** + * Value to use for rounding read-from-config label sizes. + * + * When reading the config from a printer the label width and height may be + * variable. When you set the label width to 4 inches it's translated into + * dots, and then the printer adds a calculated offset to that. This offset + * is unique per printer (so far as I have observed) and introduces noise. + * This value rounds the returned value to the nearest fraction of an inch. + * + * For example, with a rounding step of 0.25 (the default) if the printer + * returns a width 4.113 it will be rounded to 4.0 + */ + labelDimensionRoundingStep: number; + + /** Label print speed settings */ + speed: PrintSpeedSettings; + + /** The label media thermal print mode. */ + thermalPrintMode: ThermalPrintMode; + + /** The behavior of media after form printing. */ + mediaPrintMode: MediaPrintMode; + + /** Whether the label prints right-side-up or upside-down. */ + printOrientation: PrintOrientation; } /** Coordinates on a 2D plane. */ export interface Coordinate { - /** Offset from the left side of the plane, incrementing to the right. --> */ - left: number; - /** Offset from the top side of the plane, incrementing down. */ - top: number; + /** Offset from the left side of the plane, incrementing to the right. --> */ + left: number; + /** Offset from the top side of the plane, incrementing down. */ + top: number; } /** The orientation of a label as it comes out of the printer. */ export enum PrintOrientation { - /** Right-side up when the printer faces the user. */ - normal, - /** Upside-down when the printer faces the user. */ - inverted + /** Right-side up when the printer faces the user. */ + normal, + /** Upside-down when the printer faces the user. */ + inverted } /** Configured print speeds for a printer. */ export class PrintSpeedSettings { - constructor(printSpeed: PrintSpeed, slewSpeed?: PrintSpeed) { - this.printSpeed = printSpeed; - this.slewSpeed = slewSpeed ?? printSpeed; - } - /** Speed during printing media. */ - printSpeed: PrintSpeed; - /** Speed during feeding a blank label. ZPL only, same as media speed for EPL. */ - slewSpeed: PrintSpeed; - - // My kingdom for extension methods on enums in a reasonable manner. - /** Look up a speed enum from a given whole number */ - public static getSpeedFromWholeNumber(speed: number): PrintSpeed { - switch (speed) { - case 0: - return PrintSpeed.ipsAuto; - case 1: - return PrintSpeed.ips1; - case 2: - return PrintSpeed.ips2; - case 3: - return PrintSpeed.ips3; - case 4: - return PrintSpeed.ips4; - case 5: - return PrintSpeed.ips5; - case 6: - return PrintSpeed.ips6; - case 7: - return PrintSpeed.ips7; - case 8: - return PrintSpeed.ips8; - case 9: - return PrintSpeed.ips9; - case 10: - return PrintSpeed.ips10; - case 11: - return PrintSpeed.ips11; - case 12: - return PrintSpeed.ips12; - case 13: - return PrintSpeed.ips13; - case 14: - return PrintSpeed.ips14; - default: - return PrintSpeed.unknown; - } + constructor(printSpeed: PrintSpeed, slewSpeed?: PrintSpeed) { + this.printSpeed = printSpeed; + this.slewSpeed = slewSpeed ?? printSpeed; + } + + /** Speed during printing media. */ + printSpeed: PrintSpeed; + /** Speed during feeding a blank label. ZPL only, same as media speed for EPL. */ + slewSpeed: PrintSpeed; + + // My kingdom for extension methods on enums in a reasonable manner. + /** Look up a speed enum from a given whole number */ + public static getSpeedFromWholeNumber(speed: number): PrintSpeed { + switch (speed) { + case 0: + return PrintSpeed.ipsAuto; + case 1: + return PrintSpeed.ips1; + case 2: + return PrintSpeed.ips2; + case 3: + return PrintSpeed.ips3; + case 4: + return PrintSpeed.ips4; + case 5: + return PrintSpeed.ips5; + case 6: + return PrintSpeed.ips6; + case 7: + return PrintSpeed.ips7; + case 8: + return PrintSpeed.ips8; + case 9: + return PrintSpeed.ips9; + case 10: + return PrintSpeed.ips10; + case 11: + return PrintSpeed.ips11; + case 12: + return PrintSpeed.ips12; + case 13: + return PrintSpeed.ips13; + case 14: + return PrintSpeed.ips14; + default: + return PrintSpeed.unknown; } + } } /** Printer speed values in inches per second (IPS). */ export enum PrintSpeed { - unknown = -1, - /** Mobile printers can't be configured otherwise. */ - ipsAuto = 0, - /** The lowest speed a given printer supports. */ - ipsPrinterMin, - ips1, - /** EPL-only. Not often supported */ - ips1_5, // eslint-disable-line - ips2, - /** EPL-only. Not often supported */ - ips2_5, // eslint-disable-line - ips3, - /** EPL-only. Not often supported */ - ips3_5, // eslint-disable-line - ips4, - ips5, - ips6, - ips7, - ips8, - ips9, - ips10, - ips11, - ips12, - /** Not often supported */ - ips13, - /** Not often supported */ - ips14, - /** The highest speed a given printer supports. */ - ipsPrinterMax + unknown = -1, + /** Mobile printers can't be configured otherwise. */ + ipsAuto = 0, + /** The lowest speed a given printer supports. */ + ipsPrinterMin, + ips1, + /** EPL-only. Not often supported */ + ips1_5, // eslint-disable-line + ips2, + /** EPL-only. Not often supported */ + ips2_5, // eslint-disable-line + ips3, + /** EPL-only. Not often supported */ + ips3_5, // eslint-disable-line + ips4, + ips5, + ips6, + ips7, + ips8, + ips9, + ips10, + ips11, + ips12, + /** Not often supported */ + ips13, + /** Not often supported */ + ips14, + /** The highest speed a given printer supports. */ + ipsPrinterMax } /** The thermal media print mode */ export enum ThermalPrintMode { - /** Direct thermal with no ribbon. Printer must support this mode. */ - direct, - /** Thermal transfer, using a ribbon. Printer must support this mode. */ - transfer + /** Direct thermal with no ribbon. Printer must support this mode. */ + direct, + /** Thermal transfer, using a ribbon. Printer must support this mode. */ + transfer } /** Describes the way the labels are marked for the printer to detect separate labels. */ export enum LabelMediaGapDetectionMode { - /** Media is one continous label with no gaps. Used with cutters usually. */ - continuous, - /** Media is opaque with gaps betwen labels that can be sensed by the printer. */ - webSensing, - /** Media has black marks indicating label spacing. */ - markSensing, - /** Autodetect during calibration. G-series printers only. */ - autoDuringCalibration, - /** KR403 printer only. */ - continuousVariableLength + /** Media is one continuous label with no gaps. Used with cutters usually. */ + continuous, + /** Media is opaque with gaps between labels that can be sensed by the printer. */ + webSensing, + /** Media has black marks indicating label spacing. */ + markSensing, + /** Autodetect during calibration. G-series printers only. */ + autoDuringCalibration, + /** KR403 printer only. */ + continuousVariableLength } /** Printing behavior */ export enum MediaPrintMode { - /** Label advances so web is over tear bar, to be torn manually. */ - tearoff, - /** Label advances over Label Taken sensor. Printing pauses until label is removed. */ - peel, - /** Peel mode, but each label is fed to prepeel a small portion. Helps some media types. ZPL only.*/ - peelWithPrepeel, - /** Peel mode, but printer waits for button tap between labels. */ - peelWithButtonTap, - /** Label advances until web is over cutter. */ - cutter, - /** Cutter, but cut operation waits for separate command. ZPL only. */ - cutterWaitForCommand, - /** Label and liner are rewound on an external device. No backfeed motion. ZPL only. */ - rewind, - /** Label advances far enough for applicator device to grab. Printers with applicator ports only. */ - applicator, - /** Removes backfeed between RFID labels, improving throughput. RFID printers only. */ - rfid, - /** Label is moved into a presentation position. ZPL only.*/ - kiosk + /** Label advances so web is over tear bar, to be torn manually. */ + tearOff, + /** Label advances over Label Taken sensor. Printing pauses until label is removed. */ + peel, + /** Peel mode, but each label is fed to pre-peel a small portion. Helps some media types. ZPL only.*/ + peelWithPrePeel, + /** Peel mode, but printer waits for button tap between labels. */ + peelWithButtonTap, + /** Label advances until web is over cutter. */ + cutter, + /** Cutter, but cut operation waits for separate command. ZPL only. */ + cutterWaitForCommand, + /** Label and liner are rewound on an external device. No backfeed motion. ZPL only. */ + rewind, + /** Label advances far enough for applicator device to grab. Printers with applicator ports only. */ + applicator, + /** Removes backfeed between RFID labels, improving throughput. RFID printers only. */ + rfid, + /** Label is moved into a presentation position. ZPL only.*/ + kiosk } diff --git a/src/Printers/Configuration/PrinterOptions.ts b/src/Printers/Configuration/PrinterOptions.ts index 58f8864..242cd7c 100644 --- a/src/Printers/Configuration/PrinterOptions.ts +++ b/src/Printers/Configuration/PrinterOptions.ts @@ -1,126 +1,130 @@ -import { IPrinterModelInfo, UnknownPrinter } from '../Models/PrinterModel.js'; -import * as Serial from './SerialPortSettings.js'; +import { type IPrinterModelInfo, UnknownPrinter } from '../Models/PrinterModel.js'; export * from './SerialPortSettings.js'; import * as Media from './MediaOptions.js'; export * from './MediaOptions.js'; /** Firmware information about the printer that can't be modified. */ export interface IPrinterFactoryInformation { - /** The raw serial number of the printer. */ - get serialNumber(): string; - /** The model of the printer. */ - get model(): IPrinterModelInfo; - /** The firmware version information for the printer. */ - get firmware(): string; - /** The command languages the printer supports. */ - get language(): PrinterCommandLanguage; + /** The raw serial number of the printer. */ + get serialNumber(): string; + /** The model of the printer. */ + get model(): IPrinterModelInfo; + /** The firmware version information for the printer. */ + get firmware(): string; + /** The command languages the printer supports. */ + get language(): PrinterCommandLanguage; } /** Configured options for a label printer */ export class PrinterOptions implements IPrinterFactoryInformation, Media.IPrinterLabelMediaOptions { - // Read-only printer config info - private _serialNum: string; - get serialNumber(): string { - return this._serialNum; - } - private _model: IPrinterModelInfo; - get model(): IPrinterModelInfo { - return this._model; - } - - get labelDpi(): number { - return this._model.dpi; - } - - private _firmware: string; - get firmware(): string { - return this._firmware; - } - - get language(): PrinterCommandLanguage { - return this._model.commandLanguage; - } - - private _valid: boolean; - get valid(): boolean { - return this._valid; - } - - speed: Media.PrintSpeedSettings; - - darknessPercent: Media.DarknessPercent; - thermalPrintMode: Media.ThermalPrintMode; - mediaPrintMode: Media.MediaPrintMode; - printOrientation: Media.PrintOrientation; - labelGapDetectMode: Media.LabelMediaGapDetectionMode; - labelPrintOriginOffsetDots: Media.Coordinate; - - labelGapDots: number; - get labelGapInches() { - return this.dotToInch(this.labelGapDots); - } - - labelLineOffsetDots: number; - get labelLineOffsetInches() { - return this.dotToInch(this.labelLineOffsetDots); - } - - labelWidthDots: number; - get labelWidthInches() { - return this.dotToInch(this.labelWidthDots); - } - labelHeightDots: number; - get labelHeightInches() { - return this.dotToInch(this.labelHeightDots); - } - - constructor(serialNumber: string, model: IPrinterModelInfo, firmware: string, valid = true) { - this._serialNum = serialNumber; - this._model = model; - this._firmware = firmware; - this._valid = valid; - } - - /** Get a default invalid config. */ - public static invalid() { - return new PrinterOptions('', new UnknownPrinter(), '', false); - } - - private dotToInch(dots: number) { - return Math.round((dots / this.model.dpi) * 100 + Number.EPSILON) / 100; - } - - public copy(): PrinterOptions { - const copy = new PrinterOptions(this.serialNumber, this.model, this.firmware, this.valid); - copy.printOrientation = this.printOrientation; - copy.speed = this.speed; - copy.darknessPercent = this.darknessPercent; - copy.thermalPrintMode = this.thermalPrintMode; - copy.mediaPrintMode = this.mediaPrintMode; - copy.labelGapDetectMode = this.labelGapDetectMode; - copy.labelPrintOriginOffsetDots = this.labelPrintOriginOffsetDots; - copy.labelGapDots = this.labelGapDots; - copy.labelWidthDots = this.labelWidthDots; - copy.labelHeightDots = this.labelHeightDots; - - return copy; - } + // Read-only printer config info + private _serialNum: string; + get serialNumber(): string { + return this._serialNum; + } + private _model: IPrinterModelInfo; + get model(): IPrinterModelInfo { + return this._model; + } + + get labelDpi(): number { + return this._model.dpi; + } + + private _firmware: string; + get firmware(): string { + return this._firmware; + } + + get language(): PrinterCommandLanguage { + return this._model.commandLanguage; + } + + private _valid: boolean; + get valid(): boolean { + return this._valid; + } + + public labelDimensionRoundingStep = 0.25; + + speed: Media.PrintSpeedSettings = new Media.PrintSpeedSettings(Media.PrintSpeed.unknown); + darknessPercent: Media.DarknessPercent = 50; + thermalPrintMode = Media.ThermalPrintMode.direct; + mediaPrintMode = Media.MediaPrintMode.tearOff; + printOrientation = Media.PrintOrientation.normal; + labelGapDetectMode = Media.LabelMediaGapDetectionMode.webSensing; + labelPrintOriginOffsetDots: Media.Coordinate = { left: 0, top: 0 }; + + labelGapDots: number = 0; + get labelGapInches() { + return this.dotToInch(this.labelGapDots); + } + + labelLineOffsetDots: number = 0; + get labelLineOffsetInches() { + return this.dotToInch(this.labelLineOffsetDots); + } + + labelWidthDots: number = 100; + get labelWidthInches() { + return this.dotToInch(this.labelWidthDots); + } + labelHeightDots: number = 100; + get labelHeightInches() { + return this.dotToInch(this.labelHeightDots); + } + + constructor( + serialNumber: string, + model: IPrinterModelInfo, + firmware: string, + valid = true + ) { + this._serialNum = serialNumber; + this._model = model; + this._firmware = firmware; + this._valid = valid; + } + + /** Get a default invalid config. */ + public static readonly invalid = new PrinterOptions('', new UnknownPrinter(), '', false); + + private dotToInch(dots?: number) { + if (dots === undefined || this.model.dpi === undefined) { return 0; } + return Math.round((dots / this.model.dpi) * 100 + Number.EPSILON) / 100; + } + + public copy(): PrinterOptions { + const copy = new PrinterOptions(this.serialNumber, this.model, this.firmware, this.valid); + copy.printOrientation = this.printOrientation; + copy.speed = this.speed; + copy.darknessPercent = this.darknessPercent; + copy.thermalPrintMode = this.thermalPrintMode; + copy.mediaPrintMode = this.mediaPrintMode; + copy.labelGapDetectMode = this.labelGapDetectMode; + copy.labelPrintOriginOffsetDots = this.labelPrintOriginOffsetDots; + copy.labelGapDots = this.labelGapDots; + copy.labelWidthDots = this.labelWidthDots; + copy.labelHeightDots = this.labelHeightDots; + + return copy; + } } // [flags] I miss C#. /** Command languages a printer could support. One printer may support multiple. */ export enum PrinterCommandLanguage { - /** Error condition indicating autodetect failed. */ - none = 0, - /** Printer can be set to EPL mode. */ - epl = 1 << 0, - /** Printer can be set to ZPL mode. */ - zpl = 1 << 1, - /** Printer can be set to CPCL mode. */ - cpcl = 1 << 2, - - /** Printer is capable of switching between EPL and ZPL. */ - zplEmulateEpl = epl | zpl, - /** Printer is CPCL native and can emulate EPL and ZPL. */ - cpclEmulateBoth = cpcl | epl | zpl + /** Error condition indicating autodetect failed. */ + none = 0, + /** Printer can be set to EPL mode. */ + epl = 1 << 0, + /** Printer can be set to ZPL mode. */ + zpl = 1 << 1, + /** Printer can be set to CPCL mode. */ + cpcl = 1 << 2, + + /** Printer is capable of switching between EPL and ZPL. */ + zplEmulateEpl = epl | zpl, + /** Printer is CPCL native and can emulate EPL and ZPL. */ + cpclEmulateBoth = cpcl | epl | zpl } diff --git a/src/Printers/Configuration/SerialPortSettings.ts b/src/Printers/Configuration/SerialPortSettings.ts index 2db1c7b..1dc19eb 100644 --- a/src/Printers/Configuration/SerialPortSettings.ts +++ b/src/Printers/Configuration/SerialPortSettings.ts @@ -1,80 +1,80 @@ /** The serial port settings for a printer */ -export class SerialPortSettings { - /** Port baud rate. Default s9600. */ - public speed: SerialPortSpeed; - /** Port parity. Default none. */ - public parity: SerialPortParity; - /** Data bit count. Default eight. */ - public dataBits: SerialPortDataBits; - /** Stop bit count. Default one. */ - public stopBits: SerialPortStopBits; - /** Handshake mode. Default XON/XOFF. ZPL only. */ - public handshake?: SerialPortHandshake; - /** Error protocol. Default none. ZPL only. */ - public errorProtocol?: SerialPortZebraProtocol; - /** Multi-drop serial network ID, between 000 and 999. Default 000. ZPL only. */ - public networkId?: number; +export interface SerialPortSettings { + /** Port baud rate. Default s9600. */ + speed: SerialPortSpeed; + /** Port parity. Default none. */ + parity: SerialPortParity; + /** Data bit count. Default eight. */ + dataBits: SerialPortDataBits; + /** Stop bit count. Default one. */ + stopBits: SerialPortStopBits; + /** Handshake mode. Default XON/XOFF. ZPL only. */ + handshake?: SerialPortHandshake; + /** Error protocol. Default none. ZPL only. */ + errorProtocol?: SerialPortZebraProtocol; + /** Multi-drop serial network ID, between 000 and 999. Default 000. ZPL only. */ + networkId?: number; } /** Baud rate of the serial port. Not all printers support all speeds. */ export enum SerialPortSpeed { - /** Not commonly supported. */ - s110 = 110, + /** Not commonly supported. */ + s110 = 110, /** ZPL only */ - s300 = 300, + s300 = 300, /** ZPL only */ - s600 = 600, - s1200 = 1200, - s2400 = 2400, - s4800 = 4800, - s9600 = 9600, - s14400 = 14400, - s19200 = 19200, - s28800 = 28800, - s38400 = 38400, + s600 = 600, + s1200 = 1200, + s2400 = 2400, + s4800 = 4800, + s9600 = 9600, + s14400 = 14400, + s19200 = 19200, + s28800 = 28800, + s38400 = 38400, /** Not all printers */ - s57600 = 57600, + s57600 = 57600, /** Not all printers */ - s115200 = 115200 + s115200 = 115200 } /** Parity of the serial port */ export enum SerialPortParity { - none, - odd, - even + none, + odd, + even } /** Number of serial data bits */ export enum SerialPortDataBits { - seven = 7, - eight = 8 + seven = 7, + eight = 8 } /** Number of serial stop bits */ export enum SerialPortStopBits { - one = 1, - two = 2 + one = 1, + two = 2 } /** Serial protocol flow control mode. ZPL only. */ export enum SerialPortHandshake { - /** Software flow control */ - xon_xoff, //eslint-disable-line - /** Hardware flow control */ - dtr_dsr, //eslint-disable-line - /** Hardware pacing control */ - rts_cts, //eslint-disable-line - /** Auto-detect flow control based on first flow control detected. G-series printers only */ - dtr_dsr_and_xon_xoff //eslint-disable-line + /** Software flow control */ + xon_xoff, //eslint-disable-line + /** Hardware flow control */ + dtr_dsr, //eslint-disable-line + /** Hardware pacing control */ + rts_cts, //eslint-disable-line + /** Auto-detect flow control based on first flow control detected. G-series printers only */ + dtr_dsr_and_xon_xoff //eslint-disable-line } /** Error checking protocol. You probably want this to always be none. ZPL only. */ export enum SerialPortZebraProtocol { - /** No error checking handshake. Default. */ - none, - /** Send ACK/NAK packets back to host. */ - ack_nak, //eslint-disable-line - /** ack_nak with sequencing. Requires DSR/DTR. */ - zebra + /** No error checking handshake. Default. */ + none, + /** Send ACK/NAK packets back to host. */ + ack_nak, //eslint-disable-line + /** ack_nak with sequencing. Requires DSR/DTR. */ + zebra } diff --git a/test/Printers/Languages/EplPrinterCommandSet.test.ts b/src/Printers/Languages/EplPrinterCommandSet.test.ts similarity index 83% rename from test/Printers/Languages/EplPrinterCommandSet.test.ts rename to src/Printers/Languages/EplPrinterCommandSet.test.ts index 6106371..3195dca 100644 --- a/test/Printers/Languages/EplPrinterCommandSet.test.ts +++ b/src/Printers/Languages/EplPrinterCommandSet.test.ts @@ -1,10 +1,10 @@ -/// +import { expect, describe, it } from 'vitest'; import { AddImageCommand, EplPrinterCommandSet, - TranspilationFormMetadata -} from '../../../src/index.js'; -import { BitmapGRF } from '../../../src/Documents/BitmapGRF.js'; + TranspiledDocumentState +} from '../../index.js'; +import { BitmapGRF } from '../../Documents/BitmapGRF.js'; // Class pulled from jest-mock-canvas which I can't seem to actually import. class ImageData { @@ -27,7 +27,7 @@ class ImageData { return 'srgb' as PredefinedColorSpace; } - constructor(arr, w, h) { + constructor(arr: number | Uint8ClampedArray, w: number, h?: number) { if (arguments.length === 2) { if (arr instanceof Uint8ClampedArray) { if (arr.length === 0) @@ -50,7 +50,7 @@ class ImageData { this._height = height; this._data = new Uint8ClampedArray(width * height * 4); } - } else if (arguments.length === 3) { + } else if (arguments.length === 3 && h !== undefined) { if (!(arr instanceof Uint8ClampedArray)) throw new TypeError('First argument must be a Uint8ClampedArray when using 3 arguments.'); if (arr.length === 0) throw new RangeError('Source length must be a positive multiple of 4.'); @@ -73,7 +73,7 @@ class ImageData { function getImageDataInput(width: number, height: number, fill: number, alpha?: number) { const arr = new Uint8ClampedArray(width * height * 4); - if (alpha != null && alpha != fill) { + if (alpha !== undefined && alpha != fill) { for (let i = 0; i < arr.length; i += 4) { arr[i + 0] = fill; arr[i + 1] = fill; @@ -88,13 +88,13 @@ function getImageDataInput(width: number, height: number, fill: number, alpha?: const cmdSet = new EplPrinterCommandSet(); -describe('EplImageConversionToFullCommand', () => { +describe('EPL Image Conversion', () => { it('Should convert blank images to valid command', () => { const imageData = new ImageData(getImageDataInput(8, 1, 0), 8, 1); const bitmap = BitmapGRF.fromCanvasImageData(imageData, { trimWhitespace: false }); const cmd = new AddImageCommand(bitmap, {}); - const doc = new TranspilationFormMetadata(); - const resultCmd = cmdSet['addImageCommand'](cmd, doc, cmdSet); + const doc = new TranspiledDocumentState(); + const resultCmd = cmdSet['addImageCommand'](cmd, doc); const expectedCmd = Uint8Array.from([ ...new TextEncoder().encode('GW0,0,1,1,'), @@ -110,10 +110,10 @@ describe('EplImageConversionToFullCommand', () => { const bitmap = BitmapGRF.fromCanvasImageData(imageData, { trimWhitespace: false }); const cmd = new AddImageCommand(bitmap, {}); const appliedOffset = 10; - const doc = new TranspilationFormMetadata(); + const doc = new TranspiledDocumentState(); doc.horizontalOffset = appliedOffset; doc.verticalOffset = appliedOffset * 2; - const resultCmd = cmdSet['addImageCommand'](cmd, doc, cmdSet); + const resultCmd = cmdSet['addImageCommand'](cmd, doc); const expectedCmd = Uint8Array.from([ ...new TextEncoder().encode(`GW${appliedOffset},${appliedOffset * 2},1,1,`), @@ -123,11 +123,4 @@ describe('EplImageConversionToFullCommand', () => { expect(resultCmd).toEqual(expectedCmd); }); - - it('Should return noop for blank imageData', () => { - const doc = new TranspilationFormMetadata(); - const resultCmd = cmdSet['addImageCommand'](null, doc, cmdSet); - - expect(resultCmd).toEqual(new Uint8Array()); - }); }); diff --git a/src/Printers/Languages/EplPrinterCommandSet.ts b/src/Printers/Languages/EplPrinterCommandSet.ts index f2d9d14..13faafd 100644 --- a/src/Printers/Languages/EplPrinterCommandSet.ts +++ b/src/Printers/Languages/EplPrinterCommandSet.ts @@ -1,569 +1,572 @@ +/* eslint-disable no-fallthrough */ import { WebZlpError } from '../../WebZlpError.js'; import * as Options from '../Configuration/PrinterOptions.js'; import { PrinterOptions } from '../Configuration/PrinterOptions.js'; import { PrinterModelDb } from '../Models/PrinterModelDb.js'; import { PrinterModel } from '../Models/PrinterModel.js'; import { - CommandFormInclusionMode, - PrinterCommandSet, - TranspilationFormMetadata, - TranspileCommandDelegate + PrinterCommandSet, + TranspiledDocumentState, + type IPrinterExtendedCommandMapping, + exhaustiveMatchGuard } from './PrinterCommandSet.js'; import * as Commands from '../../Documents/Commands.js'; -import { PrinterCommunicationOptions } from '../PrinterCommunicationOptions.js'; +import { clampToRange } from '../../NumericRange.js'; /** Command set for communicating with an EPL II printer. */ export class EplPrinterCommandSet extends PrinterCommandSet { - private encoder = new TextEncoder(); - - get commandLanguage(): Options.PrinterCommandLanguage { - return Options.PrinterCommandLanguage.epl; - } - - get formStartCommand(): Uint8Array { - // Start of any EPL document should include a clear image buffer to prevent - // previous commands from affecting the document. - return this.encodeCommand('\r\nN'); - } - - get formEndCommand(): Uint8Array { - // There's no formal command for the end of an EPL doc, but just in case - // add a newline. - return this.encodeCommand(); - } - - protected nonFormCommands: (symbol | Commands.CommandType)[] = [ - Commands.CommandType.AutosenseLabelDimensionsCommand, - Commands.CommandType.PrintConfigurationCommand, - Commands.CommandType.QueryConfigurationCommand, - Commands.CommandType.RawDocumentCommand, - Commands.CommandType.RebootPrinterCommand - ]; - - protected transpileCommandMap = new Map< - symbol | Commands.CommandType, - TranspileCommandDelegate - >([ - /* eslint-disable prettier/prettier */ - // Ghost commands which shouldn't make it this far. - [Commands.CommandType.NewLabelCommand, this.unprocessedCommand], - [Commands.CommandType.CommandCustomSpecificCommand, this.unprocessedCommand], - [Commands.CommandType.CommandLanguageSpecificCommand, this.unprocessedCommand], - // Actually valid commands to parse - [Commands.CommandType.OffsetCommand, this.modifyOffset], - [Commands.CommandType.ClearImageBufferCommand, () => this.formStartCommand], - [Commands.CommandType.CutNowCommand, () => this.encodeCommand('C')], + private encoder = new TextEncoder(); + + get commandLanguage(): Options.PrinterCommandLanguage { + return Options.PrinterCommandLanguage.epl; + } + + get formStartCommand(): Uint8Array { + // Start of any EPL document should include a clear image buffer to prevent + // previous commands from affecting the document. + return this.encodeCommand('\r\nN'); + } + + get formEndCommand(): Uint8Array { + // There's no formal command for the end of an EPL doc, but just in case + // add a newline. + return this.encodeCommand(); + } + + protected nonFormCommands: (symbol | Commands.CommandType)[] = [ + 'AutosenseLabelDimensionsCommand', + 'PrintConfigurationCommand', + 'QueryConfigurationCommand', + 'RawDocumentCommand', + 'RebootPrinterCommand' + ]; + + constructor( + extendedCommands: Array> = [] + ) { + super(Options.PrinterCommandLanguage.epl, extendedCommands); + } + + public encodeCommand(str = '', withNewline = true): Uint8Array { + // Every command in EPL ends with a newline. + return this.encoder.encode(str + (withNewline ? '\r\n' : '')); + } + + public transpileCommand( + cmd: Commands.IPrinterCommand, + docState: TranspiledDocumentState + ): Uint8Array { + switch (cmd.type) { + default: + exhaustiveMatchGuard(cmd.type); + break; + case 'CustomCommand': + return this.extendedCommandHandler(cmd, docState); + case 'NewLabelCommand': + // Should have been compiled out at a higher step. + return this.unprocessedCommand(cmd); + + case 'RebootPrinterCommand': + return this.encodeCommand('^@'); + case 'QueryConfigurationCommand': + return this.encodeCommand('UQ'); + case 'PrintConfigurationCommand': + return this.encodeCommand('U'); + case 'SaveCurrentConfigurationCommand': + // EPL doesn't have an explicit save step. + return this.noop; + + case 'SetPrintDirectionCommand': + return this.setPrintDirectionCommand((cmd as Commands.SetPrintDirectionCommand).upsideDown); + case 'SetDarknessCommand': + return this.setDarknessCommand((cmd as Commands.SetDarknessCommand).darknessSetting); + case 'AutosenseLabelDimensionsCommand': + return this.encodeCommand('xa'); + case 'SetPrintSpeedCommand': + // EPL has no separate media slew speed setting. + return this.setPrintSpeedCommand((cmd as Commands.SetPrintSpeedCommand).speedVal); + case 'SetLabelDimensionsCommand': + return this.setLabelDimensionsCommand(cmd as Commands.SetLabelDimensionsCommand); + case 'SetLabelHomeCommand': + return this.setLabelHomeCommand(cmd as Commands.SetLabelHomeCommand, docState, this); + case 'SetLabelPrintOriginOffsetCommand': + return this.setLabelPrintOriginOffsetCommand(cmd as Commands.SetLabelPrintOriginOffsetCommand); + case 'SetLabelToContinuousMediaCommand': + return this.setLabelToContinuousMediaCommand(cmd as Commands.SetLabelToContinuousMediaCommand); + case 'SetLabelToMarkMediaCommand': + return this.setLabelToMarkMediaCommand(cmd as Commands.SetLabelToMarkMediaCommand); + case 'SetLabelToWebGapMediaCommand': + return this.setLabelToWebGapMediaCommand(cmd as Commands.SetLabelToWebGapMediaCommand); + + case 'ClearImageBufferCommand': + // Clear image buffer isn't a relevant command on ZPL printers. + // Closest equivalent is the ~JP (pause and cancel) or ~JA (cancel all) but both + // affect in-progress printing operations which is unlikely to be desired operation. + // Translate as a no-op. + return this.formStartCommand; + case 'SuppressFeedBackupCommand': // EPL uses an on/off style for form backup, it'll remain off until reenabled. - [Commands.CommandType.SuppressFeedBackupCommand, () => this.encodeCommand('JB')], + return this.encodeCommand('JB'); + case 'EnableFeedBackupCommand': // Thus EPL needs an explicit command to re-enable. - [Commands.CommandType.EnableFeedBackupCommand, () => this.encodeCommand('JF')], - [Commands.CommandType.RebootPrinterCommand, () => this.encodeCommand('^@')], - [Commands.CommandType.QueryConfigurationCommand, () => this.encodeCommand('UQ')], - [Commands.CommandType.PrintConfigurationCommand, () => this.encodeCommand('U')], - [Commands.CommandType.SaveCurrentConfigurationCommand, () => this.noop], - [Commands.CommandType.SetPrintDirectionCommand, this.setPrintDirectionCommand], - [Commands.CommandType.SetDarknessCommand, this.setDarknessCommand], - [Commands.CommandType.SetPrintSpeedCommand, this.setPrintSpeedCommand], - [Commands.CommandType.AutosenseLabelDimensionsCommand, () => this.encodeCommand('xa')], - [Commands.CommandType.SetLabelDimensionsCommand, this.setLabelDimensionsCommand], - [Commands.CommandType.SetLabelHomeCommand, this.setLabelHomeCommand], - [Commands.CommandType.SetLabelPrintOriginOffsetCommand, this.setLabelPrintOriginOffsetCommand], - [Commands.CommandType.SetLabelToContinuousMediaCommand, this.setLabelToContinuousMediaCommand], - [Commands.CommandType.SetLabelToWebGapMediaCommand, this.setLabelToWebGapMediaCommand], - [Commands.CommandType.SetLabelToMarkMediaCommand, this.setLabelToMarkMediaCommand], - [Commands.CommandType.AddImageCommand, this.addImageCommand], - [Commands.CommandType.AddLineCommand, this.addLineCommand], - [Commands.CommandType.AddBoxCommand, this.addBoxCommand], - [Commands.CommandType.PrintCommand, this.printCommand] - /* eslint-enable prettier/prettier */ - ]); - - constructor( - customCommands: Array<{ - commandType: symbol; - applicableLanguages: Options.PrinterCommandLanguage; - transpileDelegate: TranspileCommandDelegate; - commandInclusionMode: CommandFormInclusionMode; - }> = [] - ) { - super(); - - for (const newCmd of customCommands) { - if ((newCmd.applicableLanguages & this.commandLanguage) !== this.commandLanguage) { - // Command declared to not be applicable to this command set, skip it. - continue; - } - - this.transpileCommandMap.set(newCmd.commandType, newCmd.transpileDelegate); - if (newCmd.commandInclusionMode !== CommandFormInclusionMode.sharedForm) { - this.nonFormCommands.push(newCmd.commandType); - } - } + return this.encodeCommand('JF'); + + case 'OffsetCommand': + return this.modifyOffset(cmd as Commands.OffsetCommand, docState, this); + case 'RawDocumentCommand': + return this.encodeCommand((cmd as Commands.RawDocumentCommand).rawDocument, false); + case 'AddBoxCommand': + return this.addBoxCommand(cmd as Commands.AddBoxCommand, docState); + case 'AddImageCommand': + return this.addImageCommand(cmd as Commands.AddImageCommand, docState); + case 'AddLineCommand': + return this.addLineCommand(cmd as Commands.AddLineCommand, docState); + case 'CutNowCommand': + return this.encodeCommand('C'); + + case 'PrintCommand': + return this.printCommand(cmd as Commands.PrintCommand); } - - public encodeCommand(str = '', withNewline = true): Uint8Array { - // Every command in EPL ends with a newline. - return this.encoder.encode(str + (withNewline ? '\r\n' : '')); + } + + public parseConfigurationResponse( + rawText: string, + mediaOptions: Options.IPrinterLabelMediaOptions, + ): PrinterOptions { + // Raw text from the printer contains \r\n, normalize to \n. + const lines = rawText + .replaceAll('\r', '') + .split('\n') + .filter((i) => i); + + if (lines.length <= 0) { + // No config provided, can't make a valid config out of it. + return PrinterOptions.invalid; } - parseConfigurationResponse( - rawText: string, - commOpts: PrinterCommunicationOptions - ): PrinterOptions { - // Raw text from the printer contains \r\n, normalize to \n. - const lines = rawText - .replaceAll('\r', '') - .split('\n') - .filter((i) => i); - - if (lines.length <= 0) { - // No config provided, can't make a valid config out of it. - return PrinterOptions.invalid(); - } - - // We make a lot of assumptions about the format of the config output. - // Unfortunately EPL-only printers tended to have a LOT of variance on - // what they actually put into the config. Firmware versions, especially - // shipper-customzied versions, can and do omit information. - // This method attempts to get what we can out of it. - - // See the docs folder for more information on this format. - - // First line determines firmware version and model number. When splitting - // the string by spaces the last element should always be the version and - // the rest of the elements are the model number. - // UKQ1935HLU V4.29 // Normal LP244 - // UKQ1935HMU FDX V4.45 // FedEx modified LP2844 - // UKQ1935H U UPS V4.14 // UPS modified LP2844 - const header = lines[0].split(' ').filter((i) => i); - const firmwareVersion = header.pop(); - const rawModelId = header.join(' '); - - const printerInfo = { - model: PrinterModelDb.getModel(rawModelId), - firmware: firmwareVersion, - serial: 'no_serial_nm', - serialPort: undefined, - speed: undefined, - doubleBuffering: undefined, - headDistanceIn: undefined, - printerDistanceIn: undefined, - hardwareOptions: [] - }; - - const labelInfo = { - labelWidthDots: undefined, - labelGapDots: undefined, - labelGapOffsetDots: undefined, - labelHeightDots: undefined, - density: undefined, - xRef: undefined, - yRef: undefined, - orientation: undefined, - mediaMode: undefined - }; - - // All the rest of these follow some kind of standard pattern for - // each value which we can pick up with regex. The cases here are - // built out of observed configuration dumps. - for (let i = 1; i < lines.length; i++) { - const str = lines[i]; - switch (true) { - case /^S\/N.*/.test(str): - // S/N: 42A000000000 # Serial number - printerInfo.serial = str.substring(5).trim(); - break; - case /^Serial\sport/.test(str): - // Serial port:96,N,8,1 # Serial port config - printerInfo.serialPort = str.substring(12).trim(); - break; - case /^q\d+\sQ/.test(str): { - // q600 Q208,25 # Form width (q) and length (Q), with label gap - const settingsForm = str.trim().split(' '); - // Label width includes 4 dots of padding. Ish. Maybe. - labelInfo.labelWidthDots = parseInt(settingsForm[0].substring(1)) - 4; - // Length is fuzzy, depending on the second value this can be - // A: The length of the label surface - // B: The distance between black line marks - // C: The length of the form on continous media - // Format is Qp1,p2[,p3] - const length = settingsForm[1].split(','); - // p1 is always present and can be treated as the 'label height' consistently. - labelInfo.labelHeightDots = parseInt(length[0].substring(1)); - // p2 value depends on... - const rawGapMode = length[1].trim(); - if (rawGapMode === '0') { - // Length of '0' indicates continuous media. - labelInfo.mediaMode = Options.LabelMediaGapDetectionMode.continuous; - } else if (rawGapMode.startsWith('B')) { - // A B character enables black line detect mode, gap is the line width. - labelInfo.mediaMode = Options.LabelMediaGapDetectionMode.markSensing; - labelInfo.labelGapDots = parseInt(rawGapMode.substring(1)); - } else { - // Otherwise this is the gap length between labels. - labelInfo.mediaMode = Options.LabelMediaGapDetectionMode.webSensing; - labelInfo.labelGapDots = parseInt(rawGapMode); - } - // A third value is required for black line, ignored for others. - if (length[2]) { - labelInfo.labelGapOffsetDots = parseInt(length[2]); - } - break; - } - case /^S\d\sD\d\d\sR/.test(str): { - // S4 D08 R112,000 ZB UN # Config settings 2 - const settings2 = str.trim().split(' '); - const ref = settings2[2].split(','); - printerInfo.speed = parseInt(settings2[0].substring(1)); - labelInfo.density = parseInt(settings2[1].substring(1)); - labelInfo.xRef = parseInt(ref[0].substring(1)); - labelInfo.yRef = parseInt(ref[1]); - labelInfo.orientation = settings2[3].substring(1); - break; - } - case /^I\d,.,\d\d\d\sr[YN]/.test(str): { - // I8,A,001 rY JF WY # Config settings 1 - const settings1 = str.split(' '); - printerInfo.doubleBuffering = settings1[1][1] === 'Y'; - break; - } - case /^HEAD\s\s\s\susage\s=/.test(str): { - // HEAD usage = 249,392" # Odometer of the head - const headsplit = str.substring(15).split(' '); - printerInfo.headDistanceIn = headsplit[headsplit.length - 1]; - break; - } - case /^PRINTER\susage\s=/.test(str): { - // PRINTER usage = 249,392" # Odometer of the printer - const printsplit = str.substring(15).split(' '); - printerInfo.printerDistanceIn = printsplit[printsplit.length - 1]; - break; - } - case /^Option:/.test(str): - // Option:D,Ff # Config settings 4 - printerInfo.hardwareOptions = str.substring(7).split(','); - break; - case /^Line\sMode/.test(str): - // Line mode # Printer is in EPL1 mode - throw new WebZlpError( - 'Printer is in EPL1 mode, this library does not support EPL1. Reset printer.' - ); - // - // Everything else isn't parsed into something interesting. - // We explicitly parse and handle them to better identify things we don't - // parse, so we can log that information. - // - case /^Page\sMode/.test(str): - // Page mode # Printer is in EPL2 mode - // No-op, this is the mode we want in WebZLP - case /^oE.,/.test(str): - // oEv,w,x,y,z # Config settings 5 - // Line mode font substitution settings, ignored in WebZLP - case /^oU.,/.test(str): - // oUs,t,u # UNKNOWN! - // Unknown information, only seen on a UPS model so far. - case /^\d\d\s\d\d\s\d\d\s$/.test(str): - // 06 10 14 # Config setting 6 - // Not useful information, ignored in WebZLP - case /^Emem[:\s]/.test(str): - // Emem:031K,0037K avl # Soft font storage - // Emem used: 0 # Soft font storage - case /^Gmem[:\s]/.test(str): - // Gmem:000K,0037K avl # Graphics storage - // Gmem used: 0 # Graphics storage - case /^Fmem[:\s]/.test(str): - // Fmem:000.0K,060.9K avl # Form storage - // Fmem used: 0 (bytes) # Form storage - case /^Available:/.test(str): - // Available: 130559 # Total memory for Forms, Fonts, or Graphics - case /^Cover:/.test(str): - // Cover: T=118, C=129 # (T)reshold and (C)urrent Head Up (open) sensor. - case /^Image buffer size:/.test(str): - // Image buffer size:0245K # Image buffer size in use - break; - default: - console.log( - "WebZLP observed a config line from your printer that was not handled. We'd love it if you could report this bug! Send '" + - str + - "' to https://github.com/Cellivar/WebZLP/issues" - ); - break; - } - } - - // For any of the called-out sections above see the docs for WebZLP. - - if (printerInfo.model == PrinterModel.unknown) { - // Break the rule of not directly logging errors for this ask. - console.error( - `An EPL printer was detected, but WebZLP doesn't know what model it is to communicate with it. Consider submitting an issue to the project at https://github.com/Cellivar/WebZLP/issues to have your printer added so the library can work with it. The information to attach is:`, - '\nmodel:', - rawModelId, - '\nfirmware:', - printerInfo.firmware, - '\nconfigLine', - lines[0], - '\nAnd include any other details you have about your printer. Thank you!' - ); - return PrinterOptions.invalid(); - } - - // Marshall it into a real data structure as best we can. - // TODO: Better way to do this? - const expectedModel = PrinterModelDb.getModelInfo(printerInfo.model); - const options = new PrinterOptions(printerInfo.serial, expectedModel, printerInfo.firmware); - - const rawDarkness = Math.ceil(labelInfo.density * (100 / expectedModel.maxDarkness)); - options.darknessPercent = Math.max( - 0, - Math.min(rawDarkness, 100) - ) as Options.DarknessPercent; - - options.speed = new Options.PrintSpeedSettings( - options.model.fromRawSpeed(printerInfo.speed) - ); - - const labelRoundingStep = commOpts.labelDimensionRoundingStep ?? 0; - if (labelRoundingStep > 0) { - // Label size should be rounded to the step value by round-tripping the value to an inch - // then rounding, then back to dots. - const roundedWidth = this.roundToNearestStep( - labelInfo.labelWidthDots / options.model.dpi, - labelRoundingStep - ); - options.labelWidthDots = roundedWidth * options.model.dpi; - const roundedHeight = this.roundToNearestStep( - labelInfo.labelHeightDots / options.model.dpi, - labelRoundingStep - ); - options.labelHeightDots = roundedHeight * options.model.dpi; - } else { - // No rounding - options.labelWidthDots = labelInfo.labelWidthDots; - options.labelHeightDots = labelInfo.labelHeightDots; - } - - // No rounding applied to other offsets, those tend to be stable. - options.labelGapDots = labelInfo.labelGapDots; - options.labelLineOffsetDots = labelInfo.labelGapOffsetDots; - - options.labelGapDetectMode = labelInfo.mediaMode; - - options.labelPrintOriginOffsetDots = { left: labelInfo.xRef, top: labelInfo.yRef }; - - options.printOrientation = - labelInfo.orientation === 'T' - ? Options.PrintOrientation.inverted - : Options.PrintOrientation.normal; - - // Hardware options are listed as various flags. - // Presence of d or D indicates direct thermal printing, absence indicates transfer. - if (printerInfo.hardwareOptions.some((o) => o === 'd' || o === 'D')) { - options.thermalPrintMode = Options.ThermalPrintMode.direct; - } else { - options.thermalPrintMode = Options.ThermalPrintMode.transfer; + // We make a lot of assumptions about the format of the config output. + // Unfortunately EPL-only printers tended to have a LOT of variance on + // what they actually put into the config. Firmware versions, especially + // shipper-customized versions, can and do omit information. + // This method attempts to get what we can out of it. + + // See the docs folder for more information on this format. + + // First line determines firmware version and model number. When splitting + // the string by spaces the last element should always be the version and + // the rest of the elements are the model number. + // UKQ1935HLU V4.29 // Normal LP244 + // UKQ1935HMU FDX V4.45 // FedEx modified LP2844 + // UKQ1935H U UPS V4.14 // UPS modified LP2844 + const header = lines[0].split(' ').filter((i) => i); + const firmwareVersion = header.pop() ?? ''; + const rawModelId = header.join(' '); + + const model = PrinterModelDb.getModel(rawModelId); + const expectedModel = PrinterModelDb.getModelInfo(model); + + const printerInfo: { + firmware: string, + serial: string, + serialPort?: string | undefined, + speed?: number, + doubleBuffering?: boolean, + headDistanceIn?: string, + printerDistanceIn?: string, + hardwareOptions: string[] + } = { + firmware: firmwareVersion, + hardwareOptions: [], + serial: 'no_serial_nm' + }; + + const labelInfo: { + labelWidthDots?: number, + labelGapDots?: number, + labelGapOffsetDots?: number, + labelHeightDots?: number, + density: number, + xRef: number, + yRef: number, + orientation?: string, + mediaMode: Options.LabelMediaGapDetectionMode + } = { + xRef: 0, + yRef: 0, + density: (expectedModel.maxDarkness / 2), + mediaMode: Options.LabelMediaGapDetectionMode.webSensing + }; + + // All the rest of these follow some kind of standard pattern for + // each value which we can pick up with regex. The cases here are + // built out of observed configuration dumps. + for (let i = 1; i < lines.length; i++) { + const str = lines[i]; + switch (true) { + case /^S\/N.*/.test(str): + // S/N: 42A000000000 # Serial number + printerInfo.serial = str.substring(5).trim(); + break; + case /^Serial\sport/.test(str): + // Serial port:96,N,8,1 # Serial port config + printerInfo.serialPort = str.substring(12).trim(); + break; + case /^q\d+\sQ/.test(str): { + // q600 Q208,25 # Form width (q) and length (Q), with label gap + const settingsForm = str.trim().split(' '); + // Label width includes 4 dots of padding. Ish. Maybe. + labelInfo.labelWidthDots = parseInt(settingsForm[0].substring(1)) - 4; + // Length is fuzzy, depending on the second value this can be + // A: The length of the label surface + // B: The distance between black line marks + // C: The length of the form on continuous media + // Format is Qp1,p2[,p3] + const length = settingsForm[1].split(','); + // p1 is always present and can be treated as the 'label height' consistently. + labelInfo.labelHeightDots = parseInt(length[0].substring(1)); + // p2 value depends on... + const rawGapMode = length[1].trim(); + if (rawGapMode === '0') { + // Length of '0' indicates continuous media. + labelInfo.mediaMode = Options.LabelMediaGapDetectionMode.continuous; + } else if (rawGapMode.startsWith('B')) { + // A B character enables black line detect mode, gap is the line width. + labelInfo.mediaMode = Options.LabelMediaGapDetectionMode.markSensing; + labelInfo.labelGapDots = parseInt(rawGapMode.substring(1)); + } else { + // Otherwise this is the gap length between labels. + labelInfo.mediaMode = Options.LabelMediaGapDetectionMode.webSensing; + labelInfo.labelGapDots = parseInt(rawGapMode); + } + // A third value is required for black line, ignored for others. + if (length[2]) { + labelInfo.labelGapOffsetDots = parseInt(length[2]); + } + break; } - - // EPL spreads print mode across multiple settings that are mutually exclusive. - if (printerInfo.hardwareOptions.some((o) => o === 'C')) { - options.mediaPrintMode = Options.MediaPrintMode.cutter; + case /^S\d\sD\d\d\sR/.test(str): { + // S4 D08 R112,000 ZB UN # Config settings 2 + const settings2 = str.trim().split(' '); + const ref = settings2[2].split(','); + printerInfo.speed = parseInt(settings2[0].substring(1)); + labelInfo.density = parseInt(settings2[1].substring(1)); + labelInfo.xRef = parseInt(ref[0].substring(1)); + labelInfo.yRef = parseInt(ref[1]); + labelInfo.orientation = settings2[3].substring(1); + break; } - if (printerInfo.hardwareOptions.some((o) => o === 'Cp')) { - options.mediaPrintMode = Options.MediaPrintMode.cutterWaitForCommand; + case /^I\d,.,\d\d\d\sr[YN]/.test(str): { + // I8,A,001 rY JF WY # Config settings 1 + const settings1 = str.split(' '); + printerInfo.doubleBuffering = settings1[1][1] === 'Y'; + break; } - if (printerInfo.hardwareOptions.some((o) => o === 'P')) { - options.mediaPrintMode = Options.MediaPrintMode.peel; + case /^HEAD\s\s\s\susage\s=/.test(str): { + // HEAD usage = 249,392" # Odometer of the head + const headSplit = str.substring(15).split(' '); + printerInfo.headDistanceIn = headSplit[headSplit.length - 1]; + break; } - if (printerInfo.hardwareOptions.some((o) => o === 'L')) { - options.mediaPrintMode = Options.MediaPrintMode.peelWithButtonTap; + case /^PRINTER\susage\s=/.test(str): { + // PRINTER usage = 249,392" # Odometer of the printer + const printSplit = str.substring(15).split(' '); + printerInfo.printerDistanceIn = printSplit[printSplit.length - 1]; + break; } - - // TODO: more hardware options: - // - Form feed button mode (Ff, Fr, Fi) - // - Figure out what reverse gap sensor mode S means - // - Figure out how to encode C{num} for cut-after-label-count - - // TODO other options: - // Autosense settings? - // Character set? - // Error handling? - // Continuous media? - // Black mark printing? - - return options; + case /^Option:/.test(str): + // Option:D,Ff # Config settings 4 + printerInfo.hardwareOptions = str.substring(7).split(','); + break; + case /^Line\sMode/.test(str): + // Line mode # Printer is in EPL1 mode + throw new WebZlpError( + 'Printer is in EPL1 mode, this library does not support EPL1. Reset printer.' + ); + // + // Everything else isn't parsed into something interesting. + // We explicitly parse and handle them to better identify things we don't + // parse, so we can log that information. + // + case /^Page\sMode/.test(str): + // Page mode # Printer is in EPL2 mode + // No-op, this is the mode we want in WebZLP + case /^oE.,/.test(str): + // oEv,w,x,y,z # Config settings 5 + // Line mode font substitution settings, ignored in WebZLP + case /^oU.,/.test(str): + // oUs,t,u # UNKNOWN! + // Unknown information, only seen on a UPS model so far. + case /^\d\d\s\d\d\s\d\d\s$/.test(str): + // 06 10 14 # Config setting 6 + // Not useful information, ignored in WebZLP + case /^Emem[:\s]/.test(str): + // Emem:031K,0037K avl # Soft font storage + // Emem used: 0 # Soft font storage + case /^Gmem[:\s]/.test(str): + // Gmem:000K,0037K avl # Graphics storage + // Gmem used: 0 # Graphics storage + case /^Fmem[:\s]/.test(str): + // Fmem:000.0K,060.9K avl # Form storage + // Fmem used: 0 (bytes) # Form storage + case /^Available:/.test(str): + // Available: 130559 # Total memory for Forms, Fonts, or Graphics + case /^Cover:/.test(str): + // Cover: T=118, C=129 # (T)reshold and (C)urrent Head Up (open) sensor. + case /^Image buffer size:/.test(str): + // Image buffer size:0245K # Image buffer size in use + break; + default: + console.log( + "WebZLP observed a config line from your printer that was not handled. We'd love it if you could report this bug! Send '" + + str + + "' to https://github.com/Cellivar/WebZLP/issues" + ); + break; + } } - private setPrintDirectionCommand( - cmd: Commands.SetPrintDirectionCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const dir = cmd.upsideDown ? 'T' : 'B'; - return cmdSet.encodeCommand(`Z${dir}`); + // For any of the called-out sections above see the docs for WebZLP. + + if (model === PrinterModel.unknown) { + // Break the rule of not directly logging errors for this ask. + console.error( + `An EPL printer was detected, but WebZLP doesn't know what model it is to communicate with it. Consider submitting an issue to the project at https://github.com/Cellivar/WebZLP/issues to have your printer added so the library can work with it. The information to attach is:`, + '\nmodel:', + rawModelId, + '\nfirmware:', + printerInfo.firmware, + '\nconfigLine', + lines[0], + '\nAnd include any other details you have about your printer. Thank you!' + ); + return PrinterOptions.invalid; } - private setDarknessCommand( - cmd: Commands.SetDarknessCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const dark = Math.trunc(cmd.darknessSetting); - return cmdSet.encodeCommand(`D${dark}`); + // Marshall it into a real data structure as best we can. + // TODO: Better way to do this? + const options = new PrinterOptions(printerInfo.serial, expectedModel, printerInfo.firmware); + + const darkPercent = Math.ceil(labelInfo.density * (100 / expectedModel.maxDarkness)); + options.darknessPercent = clampToRange(darkPercent, 0, expectedModel.maxDarkness) as Options.DarknessPercent; + + options.speed = new Options.PrintSpeedSettings( + options.model.fromRawSpeed(printerInfo.speed) + ); + const rounding = mediaOptions.labelDimensionRoundingStep; + if (rounding > 0 && labelInfo.labelWidthDots !== undefined && labelInfo.labelHeightDots !== undefined) { + // Label size should be rounded to the step value by round-tripping the value to an inch + // then rounding, then back to dots. + const roundedWidth = this.roundToNearestStep( + labelInfo.labelWidthDots / options.model.dpi, + rounding + ); + options.labelWidthDots = roundedWidth * options.model.dpi; + const roundedHeight = this.roundToNearestStep( + labelInfo.labelHeightDots / options.model.dpi, + rounding + ); + options.labelHeightDots = roundedHeight * options.model.dpi; + } else { + // No rounding + options.labelWidthDots = labelInfo.labelWidthDots ?? 100; + options.labelHeightDots = labelInfo.labelHeightDots ?? 100; } - private setPrintSpeedCommand( - cmd: Commands.SetPrintSpeedCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - // Validation should have happened on setup, printer will just reject - // invalid speeds. - // EPL has no separate media slew speed setting. - return cmdSet.encodeCommand(`S${cmd.speedVal}`); - } + // No rounding applied to other offsets, those tend to be stable. + options.labelGapDots = labelInfo.labelGapDots ?? 0; + options.labelLineOffsetDots = labelInfo.labelGapOffsetDots ?? 0; - private setLabelDimensionsCommand( - cmd: Commands.SetLabelDimensionsCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const width = Math.trunc(cmd.widthInDots); - const widthCmd = cmdSet.encodeCommand(`q${width}`); - if (cmd.setsHeight) { - const height = Math.trunc(cmd.heightInDots); - const gap = Math.trunc(cmd.gapLengthInDots); - const heightCmd = cmdSet.encodeCommand(`Q${height},${gap}`); - return cmdSet.combineCommands(widthCmd, heightCmd); - } - return widthCmd; - } + options.labelGapDetectMode = labelInfo.mediaMode; - private setLabelHomeCommand( - cmd: Commands.SetLabelHomeCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - return this.modifyOffset( - new Commands.OffsetCommand(cmd.xOffset, cmd.yOffset, true), - outDoc, - cmdSet - ); - } + options.labelPrintOriginOffsetDots = { left: labelInfo.xRef, top: labelInfo.yRef }; - private setLabelPrintOriginOffsetCommand( - cmd: Commands.SetLabelPrintOriginOffsetCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const xOffset = Math.trunc(cmd.xOffset); - const yOffset = Math.trunc(cmd.yOffset); - return cmdSet.encodeCommand(`R${xOffset},${yOffset}`); - } + options.printOrientation = + labelInfo.orientation === 'T' + ? Options.PrintOrientation.inverted + : Options.PrintOrientation.normal; - private setLabelToContinuousMediaCommand( - cmd: Commands.SetLabelToContinuousMediaCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - // EPL seems to not have a static label length? All labels are variable? - // Needs testing. - const length = Math.trunc(cmd.labelLengthInDots); - return cmdSet.encodeCommand(`Q${length},0`); + // Hardware options are listed as various flags. + // Presence of d or D indicates direct thermal printing, absence indicates transfer. + if (printerInfo.hardwareOptions.some((o) => o === 'd' || o === 'D')) { + options.thermalPrintMode = Options.ThermalPrintMode.direct; + } else { + options.thermalPrintMode = Options.ThermalPrintMode.transfer; } - private setLabelToWebGapMediaCommand( - cmd: Commands.SetLabelToWebGapMediaCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.labelLengthInDots); - const gap = Math.trunc(cmd.labelGapInDots); - return cmdSet.encodeCommand(`Q${length},${gap}`); + // EPL spreads print mode across multiple settings that are mutually exclusive. + if (printerInfo.hardwareOptions.some((o) => o === 'C')) { + options.mediaPrintMode = Options.MediaPrintMode.cutter; } - - private setLabelToMarkMediaCommand( - cmd: Commands.SetLabelToMarkMediaCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.labelLengthInDots); - const lineLength = Math.trunc(cmd.blackLineThicknessInDots); - const lineOffset = Math.trunc(cmd.blackLineOffset); - return cmdSet.encodeCommand(`Q${length},B${lineLength},${lineOffset}`); + if (printerInfo.hardwareOptions.some((o) => o === 'Cp')) { + options.mediaPrintMode = Options.MediaPrintMode.cutterWaitForCommand; } - - private printCommand( - cmd: Commands.PrintCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const total = Math.trunc(cmd.count); - const dup = Math.trunc(cmd.additionalDuplicateOfEach); - return cmdSet.encodeCommand(`P${total},${dup}`); + if (printerInfo.hardwareOptions.some((o) => o === 'P')) { + options.mediaPrintMode = Options.MediaPrintMode.peel; } - - private addImageCommand( - cmd: Commands.AddImageCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - if (cmd?.bitmap == null) { - return cmdSet.noop; - } - - // EPL only supports raw binary, get that. - const bitmap = cmd.bitmap; - const buffer = bitmap.toBinaryGRF(); - - // Add the text command prefix to the buffer data - const parameters = [ - 'GW' + Math.trunc(outDoc.horizontalOffset + bitmap.boundingBox.paddingLeft), - Math.trunc(outDoc.verticalOffset + bitmap.boundingBox.paddingTop), - bitmap.bytesPerRow, - bitmap.height - ]; - // Bump the offset according to the image being added. - outDoc.verticalOffset += bitmap.boundingBox.height; - const rawCmd = cmdSet.encodeCommand(parameters.join(',') + ',', false); - return cmdSet.combineCommands( - rawCmd, - cmdSet.combineCommands(buffer, cmdSet.encodeCommand('')) - ); + if (printerInfo.hardwareOptions.some((o) => o === 'L')) { + options.mediaPrintMode = Options.MediaPrintMode.peelWithButtonTap; } - private addLineCommand( - cmd: Commands.AddLineCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.lengthInDots) || 0; - const height = Math.trunc(cmd.heightInDots) || 0; - let drawMode = 'LO'; - switch (cmd.color) { - case Commands.DrawColor.black: - drawMode = 'LO'; - break; - case Commands.DrawColor.white: - drawMode = 'LW'; - break; - } - - return cmdSet.encodeCommand( - `${drawMode}${outDoc.horizontalOffset},${outDoc.verticalOffset},${length},${height}` - ); + // TODO: more hardware options: + // - Form feed button mode (Ff, Fr, Fi) + // - Figure out what reverse gap sensor mode S means + // - Figure out how to encode C{num} for cut-after-label-count + + // TODO other options: + // Autosense settings? + // Character set? + // Error handling? + // Continuous media? + // Black mark printing? + + return options; + } + + private setPrintDirectionCommand( + upsideDown: boolean + ): Uint8Array { + const dir = upsideDown ? 'T' : 'B'; + return this.encodeCommand(`Z${dir}`); + } + + private setDarknessCommand( + darkness: number + ): Uint8Array { + const dark = Math.trunc(darkness); + return this.encodeCommand(`D${dark}`); + } + + private setPrintSpeedCommand( + speed: number + ): Uint8Array { + // Validation should have happened on setup, printer will just reject + // invalid speeds. + return this.encodeCommand(`S${speed}`); + } + + private setLabelDimensionsCommand( + cmd: Commands.SetLabelDimensionsCommand, + ): Uint8Array { + const width = Math.trunc(cmd.widthInDots); + const widthCmd = this.encodeCommand(`q${width}`); + if (cmd.setsHeight && cmd.heightInDots !== undefined && cmd.gapLengthInDots !== undefined) { + const height = Math.trunc(cmd.heightInDots); + const gap = Math.trunc(cmd.gapLengthInDots); + const heightCmd = this.encodeCommand(`Q${height},${gap}`); + return this.combineCommands(widthCmd, heightCmd); } - - private addBoxCommand( - cmd: Commands.AddBoxCommand, - outDoc: TranspilationFormMetadata, - cmdSet: EplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.lengthInDots) || 0; - const height = Math.trunc(cmd.heightInDots) || 0; - const thickness = Math.trunc(cmd.thickness) || 0; - - return cmdSet.encodeCommand( - `X${outDoc.horizontalOffset},${outDoc.verticalOffset},${thickness},${length},${height}` - ); + return widthCmd; + } + + private setLabelHomeCommand( + cmd: Commands.SetLabelHomeCommand, + outDoc: TranspiledDocumentState, + cmdSet: EplPrinterCommandSet + ): Uint8Array { + return this.modifyOffset( + new Commands.OffsetCommand(cmd.xOffset, cmd.yOffset, true), + outDoc, + cmdSet + ); + } + + private setLabelPrintOriginOffsetCommand( + cmd: Commands.SetLabelPrintOriginOffsetCommand, + ): Uint8Array { + const xOffset = Math.trunc(cmd.xOffset); + const yOffset = Math.trunc(cmd.yOffset); + return this.encodeCommand(`R${xOffset},${yOffset}`); + } + + private setLabelToContinuousMediaCommand( + cmd: Commands.SetLabelToContinuousMediaCommand, + ): Uint8Array { + // EPL seems to not have a static label length? All labels are variable? + // Needs testing. + const length = Math.trunc(cmd.labelLengthInDots); + return this.encodeCommand(`Q${length},0`); + } + + private setLabelToWebGapMediaCommand( + cmd: Commands.SetLabelToWebGapMediaCommand, + ): Uint8Array { + const length = Math.trunc(cmd.labelLengthInDots); + const gap = Math.trunc(cmd.labelGapInDots); + return this.encodeCommand(`Q${length},${gap}`); + } + + private setLabelToMarkMediaCommand( + cmd: Commands.SetLabelToMarkMediaCommand, + ): Uint8Array { + const length = Math.trunc(cmd.labelLengthInDots); + const lineLength = Math.trunc(cmd.blackLineThicknessInDots); + const lineOffset = Math.trunc(cmd.blackLineOffset); + return this.encodeCommand(`Q${length},B${lineLength},${lineOffset}`); + } + + private printCommand( + cmd: Commands.PrintCommand, + ): Uint8Array { + const total = Math.trunc(cmd.count); + const dup = Math.trunc(cmd.additionalDuplicateOfEach); + return this.encodeCommand(`P${total},${dup}`); + } + + private addImageCommand( + cmd: Commands.AddImageCommand, + outDoc: TranspiledDocumentState, + ): Uint8Array { + // EPL only supports raw binary, get that. + const bitmap = cmd.bitmap; + const buffer = bitmap.toBinaryGRF(); + + // Add the text command prefix to the buffer data + const parameters = [ + 'GW' + Math.trunc(outDoc.horizontalOffset + bitmap.boundingBox.paddingLeft), + Math.trunc(outDoc.verticalOffset + bitmap.boundingBox.paddingTop), + bitmap.bytesPerRow, + bitmap.height + ]; + // Bump the offset according to the image being added. + outDoc.verticalOffset += bitmap.boundingBox.height; + const rawCmd = this.encodeCommand(parameters.join(',') + ',', false); + return this.combineCommands( + rawCmd, + this.combineCommands(buffer, this.encodeCommand('')) + ); + } + + private addLineCommand( + cmd: Commands.AddLineCommand, + outDoc: TranspiledDocumentState, + ): Uint8Array { + const length = Math.trunc(cmd.lengthInDots) || 0; + const height = Math.trunc(cmd.heightInDots) || 0; + let drawMode = 'LO'; + switch (cmd.color) { + case Commands.DrawColor.black: + drawMode = 'LO'; + break; + case Commands.DrawColor.white: + drawMode = 'LW'; + break; } + + return this.encodeCommand( + `${drawMode}${outDoc.horizontalOffset},${outDoc.verticalOffset},${length},${height}` + ); + } + + private addBoxCommand( + cmd: Commands.AddBoxCommand, + outDoc: TranspiledDocumentState, + ): Uint8Array { + const length = Math.trunc(cmd.lengthInDots) || 0; + const height = Math.trunc(cmd.heightInDots) || 0; + const thickness = Math.trunc(cmd.thickness) || 0; + + return this.encodeCommand( + `X${outDoc.horizontalOffset},${outDoc.verticalOffset},${thickness},${length},${height}` + ); + } } diff --git a/src/Printers/Languages/PrinterCommandSet.ts b/src/Printers/Languages/PrinterCommandSet.ts index 376badb..63d6856 100644 --- a/src/Printers/Languages/PrinterCommandSet.ts +++ b/src/Printers/Languages/PrinterCommandSet.ts @@ -1,297 +1,324 @@ -import { CompiledDocument, IDocument } from '../../Documents/Document.js'; +import { CompiledDocument, type IDocument } from '../../Documents/Document.js'; import { WebZlpError } from '../../WebZlpError.js'; -import { PrinterCommandLanguage, PrinterOptions } from '../Configuration/PrinterOptions.js'; +import { PrinterCommandLanguage, PrinterOptions, type IPrinterLabelMediaOptions } from '../Configuration/PrinterOptions.js'; import * as Commands from '../../Documents/Commands.js'; -import { PrinterCommunicationOptions } from '../PrinterCommunicationOptions.js'; -export type TranspileCommandDelegate = ( - cmd: Commands.IPrinterCommand, - formDoc: TranspilationFormMetadata, - commandSet: PrinterCommandSet -) => Uint8Array; +/** A manifest for a custom extended printer command. */ +export interface IPrinterExtendedCommandMapping { + extendedTypeSymbol: symbol, + delegate: TranspileCommandDelegate, +} + +export type TranspileCommandDelegate = ( + cmd: Commands.IPrinterCommand, + formDoc: TranspiledDocumentState, + commandSet: PrinterCommandSet +) => TOutput; type RawCommandForm = { commands: Array; withinForm: boolean }; export abstract class PrinterCommandSet { - /** Encode a raw string command into a Uint8Array according to the command language rules. */ - public abstract encodeCommand(str?: string, withNewline?: boolean): Uint8Array; - - private readonly _noop = new Uint8Array(); - /** Get an empty command to be used as a no-op. */ - protected get noop() { - return this._noop; - } - - /** Gets the command to start a new form. */ - protected abstract get formStartCommand(): Uint8Array; - /** Gets the command to end a form. */ - protected abstract get formEndCommand(): Uint8Array; - /** Gets the command language this command set implements */ - abstract get commandLanguage(): PrinterCommandLanguage; - - protected abstract transpileCommandMap: Map< - symbol | Commands.CommandType, - TranspileCommandDelegate - >; - - /** Transpile a command to its native command equivalent. */ - protected transpileCommand( - command: Commands.IPrinterCommand, - formMetadata: TranspilationFormMetadata - ) { - let lookup: symbol | Commands.CommandType; - if ( - command.type === Commands.CommandType.CommandCustomSpecificCommand || - command.type === Commands.CommandType.CommandLanguageSpecificCommand - ) { - lookup = (command as Commands.IPrinterExtendedCommand).typeExtended; - } else { - lookup = command.type; - } - - if (!lookup) { - throw new DocumentValidationError( - `Command '${command.constructor.name}' did not have a valid lookup element. If you're trying to implement a custom command check the documentation for correct formatting.` - ); - } - - const func = this.transpileCommandMap.get(lookup); - if (func === undefined) { - throw new DocumentValidationError( - // eslint-disable-next-line prettier/prettier - `Unknown command '${command.constructor.name}' was not found in the command map for ${PrinterCommandLanguage[this.commandLanguage]} command language. If you're trying to implement a custom command check the documentation for correctly adding mappings.` - ); - } - - return func(command, formMetadata, this); - } - - public transpileDoc(doc: IDocument): Readonly { - const validationErrors = []; - const { forms, effects } = this.splitCommandsByFormInclusion( - doc.commands, - doc.commandReorderBehavior - ); - - const commandsWithMaybeErrors = forms.flatMap((form) => this.transpileForm(form)); - const errs = commandsWithMaybeErrors.filter( - (e): e is DocumentValidationError => !(e instanceof Uint8Array) - ); - if (errs.length > 0) { - throw new DocumentValidationError( - 'One or more validation errors occurred transpiling the document.', - validationErrors - ); - } - - // Combine the separate individual documents into a single command array. - const buffer = commandsWithMaybeErrors.reduce((accumulator, cmd) => { - if (!(cmd instanceof Uint8Array)) { - throw new DocumentValidationError( - 'Document validation error present after checking for one!?!? Error in WebZLP!', - [cmd] - ); - } - return this.combineCommands(accumulator as Uint8Array, cmd); - // We start with an explicit newline, to avoid possible previous commands partially sent - }, this.encodeCommand()); - - const out = new CompiledDocument(this.commandLanguage, effects, buffer); - return Object.freeze(out); + /** Encode a raw string command into a Uint8Array according to the command language rules. */ + public abstract encodeCommand(str?: string, withNewline?: boolean): Uint8Array; + + private readonly _noop = new Uint8Array(); + /** Get an empty command to be used as a no-op. */ + protected get noop() { + return this._noop; + } + + /** Gets the command to start a new form. */ + protected abstract get formStartCommand(): Uint8Array; + /** Gets the command to end a form. */ + protected abstract get formEndCommand(): Uint8Array; + /** Gets the command language this command set implements */ + abstract get commandLanguage(): PrinterCommandLanguage; + + protected extendedCommandMap = new Map>; + + protected constructor( + public readonly implementedLanguage: PrinterCommandLanguage, + extendedCommands: Array> = [] + ) { + extendedCommands.forEach(c => this.extendedCommandMap.set(c.extendedTypeSymbol, c.delegate)); + } + + /** Transpile a command to its native command equivalent. */ + public abstract transpileCommand( + cmd: Commands.IPrinterCommand, + docState: TranspiledDocumentState + ): Uint8Array | TranspileDocumentError; + + // protected transpileCommand( + // command: Commands.IPrinterCommand, + // formMetadata: TranspilationFormMetadata + // ) { + // let lookup: symbol | Commands.CommandType; + // if ( + // command.type === Commands.CommandType.CommandCustomSpecificCommand || + // command.type === Commands.CommandType.CommandLanguageSpecificCommand + // ) { + // lookup = (command as Commands.IPrinterExtendedCommand).typeExtended; + // } else { + // lookup = command.type; + // } + + // if (!lookup) { + // throw new TranspileDocumentError( + // `Command '${command.constructor.name}' did not have a valid lookup element. If you're trying to implement a custom command check the documentation for correct formatting.` + // ); + // } + + // const func = this.transpileCommandMap.get(lookup); + // if (func === undefined) { + // throw new TranspileDocumentError( + // `Unknown command '${command.constructor.name}' was not found in the command map for ${PrinterCommandLanguage[this.commandLanguage]} command language. If you're trying to implement a custom command check the documentation for correctly adding mappings.` + // ); + // } + + // return func(command, formMetadata, this); + // } + + protected extendedCommandHandler( + cmd: Commands.IPrinterCommand, + docState: TranspiledDocumentState + ) { + const lookup = (cmd as Commands.IPrinterExtendedCommand).typeExtended; + if (!lookup) { + throw new TranspileDocumentError( + `Command '${cmd.constructor.name}' did not have a value for typeExtended. If you're trying to implement a custom command check the documentation.` + ) } - private transpileForm({ - commands, - withinForm - }: RawCommandForm): Array { - const formMetadata = new TranspilationFormMetadata(); - const transpiledCommands = commands.map((cmd) => this.transpileCommand(cmd, formMetadata)); - if (withinForm) { - transpiledCommands.unshift(this.formStartCommand); - transpiledCommands.push(this.formEndCommand); - } - - return transpiledCommands; - } + const cmdHandler = this.extendedCommandMap.get(lookup); - private splitCommandsByFormInclusion( - commands: ReadonlyArray, - reorderBehavior: Commands.CommandReorderBehavior - ): { forms: Array; effects: Commands.PrinterCommandEffectFlags } { - const forms: Array = []; - const nonForms: Array = []; - let effects = Commands.PrinterCommandEffectFlags.none; - for (const command of commands) { - effects |= command.printerEffectFlags; - if ( - this.isCommandNonFormCommand(command) && - reorderBehavior === Commands.CommandReorderBehavior.nonFormCommandsAfterForms - ) { - nonForms.push({ commands: [command], withinForm: false }); - continue; - } - - if (command.type == Commands.CommandType.NewLabelCommand) { - // Since form bounding is implicit this is our indicator to break - // between separate forms to be printed separately. - forms.push({ commands: [], withinForm: true }); - continue; - } - - // Anything else just gets tossed onto the stack of the current form, if it exists. - if (forms.at(-1) === undefined) { - forms.push({ commands: [], withinForm: true }); - } - forms.at(-1).commands.push(command); - } - - // TODO: If the day arises we need to configure non-form commands _before_ the form - // this will need to be made more clever. - return { forms: forms.concat(nonForms), effects }; + if (cmdHandler === undefined) { + throw new TranspileDocumentError( + `Unknown command '${cmd.constructor.name}' was not found in the command map for ${this.commandLanguage} command language. If you're trying to implement a custom command check the documentation for correctly adding mappings.` + ); } - - /** List of commands which must not appear within a form, according to this language's rules */ - protected abstract nonFormCommands: Array; - - private isCommandNonFormCommand(command: Commands.IPrinterCommand) { - let id: symbol | Commands.CommandType; - if ( - command.type === Commands.CommandType.CommandCustomSpecificCommand || - command.type === Commands.CommandType.CommandLanguageSpecificCommand - ) { - id = (command as Commands.IPrinterExtendedCommand).typeExtended; - } else { - id = command.type; - } - - return this.nonFormCommands.includes(id); + return cmdHandler(cmd, docState, this); + } + + public transpileDoc(doc: IDocument): Readonly { + const validationErrors: TranspileDocumentError[] = []; + const { forms, effects } = this.splitCommandsByFormInclusion( + doc.commands, + doc.commandReorderBehavior + ); + + const commandsWithMaybeErrors = forms.flatMap((form) => this.transpileForm(form)); + const errs = commandsWithMaybeErrors.filter( + (e): e is TranspileDocumentError => !(e instanceof Uint8Array) + ); + if (errs.length > 0) { + throw new TranspileDocumentError( + 'One or more validation errors occurred transpiling the document.', + validationErrors + ); } - protected unprocessedCommand(cmd: Commands.IPrinterCommand): Uint8Array { - throw new DocumentValidationError( - `Unhandled meta-command '${cmd.constructor.name}' was not preprocessed. This is a bug in WebZLP, please submit an issue.` + // Combine the separate individual documents into a single command array. + const buffer = commandsWithMaybeErrors.reduce((accumulator, cmd) => { + if (!(cmd instanceof Uint8Array)) { + throw new TranspileDocumentError( + 'Document validation error present after checking for one!?!? Error in WebZLP!', + [cmd] ); + } + return this.combineCommands(accumulator as Uint8Array, cmd); + // We start with an explicit newline, to avoid possible previous commands partially sent + }, this.encodeCommand()); + + const out = new CompiledDocument(this.commandLanguage, effects, buffer); + return Object.freeze(out); + } + + private transpileForm({ + commands, + withinForm + }: RawCommandForm): Array { + const formMetadata = new TranspiledDocumentState(); + const transpiledCommands = commands.map((cmd) => this.transpileCommand(cmd, formMetadata)); + if (withinForm) { + transpiledCommands.unshift(this.formStartCommand); + transpiledCommands.push(this.formEndCommand); } - /** - * Round a raw value to the nearest step. - */ - protected roundToNearestStep(value: number, step: number): number { - const inverse = 1.0 / step; - return Math.round(value * inverse) / inverse; - } - - /** Strip a string of invalid characters for a command. */ - protected cleanString(str: string) { - return str - .replace(/\\/gi, '\\\\') - .replace(/"/gi, '\\"') - .replace(/[\r\n]+/gi, ' '); + return transpiledCommands; + } + + private splitCommandsByFormInclusion( + commands: ReadonlyArray, + reorderBehavior: Commands.CommandReorderBehavior + ): { forms: Array; effects: Commands.PrinterCommandEffectFlags } { + const forms: Array = []; + const nonForms: Array = []; + let effects = Commands.PrinterCommandEffectFlags.none; + for (const command of commands) { + effects |= command.printerEffectFlags; + if ( + this.isCommandNonFormCommand(command) && + reorderBehavior === Commands.CommandReorderBehavior.nonFormCommandsAfterForms + ) { + nonForms.push({ commands: [command], withinForm: false }); + continue; + } + + if (command.type === 'NewLabelCommand') { + // Since form bounding is implicit this is our indicator to break + // between separate forms to be printed separately. + forms.push({ commands: [], withinForm: true }); + continue; + } + + // Anything else just gets tossed onto the stack of the current form, if it exists. + const lastForm = forms.at(-1); + if (lastForm === undefined) { + forms.push({ commands: [command], withinForm: true }); + } else { + lastForm.commands.push(command); + } } - /** Apply an offset command to a document. */ - protected modifyOffset( - cmd: Commands.OffsetCommand, - outDoc: TranspilationFormMetadata, - cmdSet: PrinterCommandSet - ) { - const newHoriz = cmd.absolute ? cmd.horizontal : outDoc.horizontalOffset + cmd.horizontal; - outDoc.horizontalOffset = newHoriz < 0 ? 0 : newHoriz; - if (cmd.vertical) { - const newVert = cmd.absolute ? cmd.vertical : outDoc.verticalOffset + cmd.vertical; - outDoc.verticalOffset = newVert < 0 ? 0 : newVert; - } - return cmdSet.noop; - } - - /** Combine two commands into one command array. */ - protected combineCommands(cmd1: Uint8Array, cmd2: Uint8Array) { - const merged = new Uint8Array(cmd1.length + cmd2.length); - merged.set(cmd1); - merged.set(cmd2, cmd1.length); - return merged; - } - - /** Clamp a number to a given range of values. */ - protected clampToRange(value: number, min: number, max: number) { - return Math.min(Math.max(value, min), max); + // TODO: If the day arises we need to configure non-form commands _before_ the form + // this will need to be made more clever. + return { forms: forms.concat(nonForms), effects }; + } + + /** List of commands which must not appear within a form, according to this language's rules */ + protected abstract nonFormCommands: Array; + + private isCommandNonFormCommand(command: Commands.IPrinterCommand) { + return this.nonFormCommands.includes( + command.type === 'CustomCommand' + ? (command as Commands.IPrinterExtendedCommand).typeExtended + : command.type + ); + } + + protected unprocessedCommand(cmd: Commands.IPrinterCommand): Uint8Array { + throw new TranspileDocumentError( + `Unhandled meta-command '${cmd.constructor.name}' was not preprocessed. This is a bug in WebZLP, please submit an issue.` + ); + } + + /** + * Round a raw value to the nearest step. + */ + protected roundToNearestStep(value: number, step: number): number { + const inverse = 1.0 / step; + return Math.round(value * inverse) / inverse; + } + + /** Strip a string of invalid characters for a command. */ + protected cleanString(str: string) { + return str + .replace(/\\/gi, '\\\\') + .replace(/"/gi, '\\"') + .replace(/[\r\n]+/gi, ' '); + } + + /** Apply an offset command to a document. */ + protected modifyOffset( + cmd: Commands.OffsetCommand, + outDoc: TranspiledDocumentState, + cmdSet: PrinterCommandSet + ) { + const newHoriz = cmd.absolute ? cmd.horizontal : outDoc.horizontalOffset + cmd.horizontal; + outDoc.horizontalOffset = newHoriz < 0 ? 0 : newHoriz; + if (cmd.vertical) { + const newVert = cmd.absolute ? cmd.vertical : outDoc.verticalOffset + cmd.vertical; + outDoc.verticalOffset = newVert < 0 ? 0 : newVert; } + return cmdSet.noop; + } + + /** Combine two commands into one command array. */ + protected combineCommands(cmd1: Uint8Array, cmd2: Uint8Array) { + const merged = new Uint8Array(cmd1.length + cmd2.length); + merged.set(cmd1); + merged.set(cmd2, cmd1.length); + return merged; + } + + /** Parse the response of a configuration inqury in the command set language. */ + abstract parseConfigurationResponse( + rawText: string, + mediaOptions: IPrinterLabelMediaOptions + ): PrinterOptions; +} - /** Parse the response of a configuration inqury in the command set language. */ - abstract parseConfigurationResponse( - rawText: string, - commOpts: PrinterCommunicationOptions - ): PrinterOptions; +export function exhaustiveMatchGuard(_: never): never { + throw new Error('Invalid case received!' + _); } /** How a command should be wrapped into a form, if at all */ export enum CommandFormInclusionMode { - /** Command can appear in a shared form with other commands. */ - sharedForm = 0, - /** Command should not be wrapped in a form at all. */ - noForm + /** Command can appear in a shared form with other commands. */ + sharedForm = 0, + /** Command should not be wrapped in a form at all. */ + noForm } export class TranspilationFormList { - private _documents: Array = [new TranspilationFormMetadata()]; - public get documents(): ReadonlyArray { - return this._documents; - } - - private activeDocumentIdx = 0; - public get currentDocument() { - return this._documents[this.activeDocumentIdx]; - } - - public addNewDocument() { - this._documents.push(new TranspilationFormMetadata()); - this.activeDocumentIdx = this._documents.length - 1; - } + private _documents: Array = [new TranspiledDocumentState()]; + public get documents(): ReadonlyArray { + return this._documents; + } + + private activeDocumentIdx = 0; + public get currentDocument() { + return this._documents[this.activeDocumentIdx]; + } + + public addNewDocument() { + this._documents.push(new TranspiledDocumentState()); + this.activeDocumentIdx = this._documents.length - 1; + } } /** Class for storing in-progress document generation information */ -export class TranspilationFormMetadata { - horizontalOffset = 0; - verticalOffset = 0; - lineSpacingDots = 5; - - dpi: number; - - commandEffectFlags = Commands.PrinterCommandEffectFlags.none; +export class TranspiledDocumentState { + horizontalOffset = 0; + verticalOffset = 0; + lineSpacingDots = 5; - rawCmdBuffer: Array = []; + commandEffectFlags = Commands.PrinterCommandEffectFlags.none; - /** Add a raw command to the internal buffer. */ - addRawCommand(array: Uint8Array) { - if (array && array.length > 0) { - this.rawCmdBuffer.push(array); - } - } + rawCmdBuffer: Array = []; - /** - * Gets a single buffer of the internal command set. - */ - get combinedBuffer(): Uint8Array { - const bufferLen = this.rawCmdBuffer.reduce((sum, arr) => sum + arr.byteLength, 0); - return this.rawCmdBuffer.reduce( - (accumulator, arr) => { - accumulator.buffer.set(arr, accumulator.offset); - return { ...accumulator, offset: arr.byteLength + accumulator.offset }; - }, - { buffer: new Uint8Array(bufferLen), offset: 0 } - ).buffer; + /** Add a raw command to the internal buffer. */ + addRawCommand(array: Uint8Array) { + if (array && array.length > 0) { + this.rawCmdBuffer.push(array); } + } + + /** + * Gets a single buffer of the internal command set. + */ + get combinedBuffer(): Uint8Array { + const bufferLen = this.rawCmdBuffer.reduce((sum, arr) => sum + arr.byteLength, 0); + return this.rawCmdBuffer.reduce( + (accumulator, arr) => { + accumulator.buffer.set(arr, accumulator.offset); + return { ...accumulator, offset: arr.byteLength + accumulator.offset }; + }, + { buffer: new Uint8Array(bufferLen), offset: 0 } + ).buffer; + } } -/** Represents an error when validating a document against a printer's capabilties. */ -export class DocumentValidationError extends WebZlpError { - private _innerErrors: DocumentValidationError[] = []; - get innerErrors() { - return this._innerErrors; - } - - constructor(message: string, innerErrors?: DocumentValidationError[]) { - super(message); - this._innerErrors = innerErrors; - } +/** Represents an error when validating a document against a printer's capabilities. */ +export class TranspileDocumentError extends WebZlpError { + private _innerErrors: TranspileDocumentError[] = []; + get innerErrors() { + return this._innerErrors; + } + + constructor(message: string, innerErrors?: TranspileDocumentError[]) { + super(message); + this._innerErrors = innerErrors ?? []; + } } diff --git a/src/Printers/Languages/ZplPrinterCommandSet.ts b/src/Printers/Languages/ZplPrinterCommandSet.ts index 87ff44e..40e7278 100644 --- a/src/Printers/Languages/ZplPrinterCommandSet.ts +++ b/src/Printers/Languages/ZplPrinterCommandSet.ts @@ -1,554 +1,540 @@ import * as Options from '../Configuration/PrinterOptions.js'; import { - PrinterCommandSet, - TranspilationFormMetadata, - TranspileCommandDelegate, - CommandFormInclusionMode + PrinterCommandSet, + TranspiledDocumentState, + type IPrinterExtendedCommandMapping, + exhaustiveMatchGuard } from './PrinterCommandSet.js'; import * as Commands from '../../Documents/Commands.js'; import { AutodetectedPrinter, PrinterModel } from '../Models/PrinterModel.js'; import { PrinterModelDb } from '../Models/PrinterModelDb.js'; -import { PrinterCommunicationOptions } from '../PrinterCommunicationOptions.js'; +import { clampToRange } from '../../NumericRange.js'; export class ZplPrinterCommandSet extends PrinterCommandSet { - private encoder = new TextEncoder(); - - get commandLanguage(): Options.PrinterCommandLanguage { - return Options.PrinterCommandLanguage.zpl; - } - - get formStartCommand(): Uint8Array { - // All ZPL documents start with the start-of-document command. - return this.encodeCommand('\n^XA\n'); - } - - get formEndCommand(): Uint8Array { - // All ZPL documents end with the end-of-document command. - return this.encodeCommand('\n^XZ\n'); - } - - encodeCommand(str = '', withNewline = true): Uint8Array { - // TODO: ZPL supports omitting the newline, figure out a clever way to - // handle situations where newlines are optional to reduce line noise. - return this.encoder.encode(str + (withNewline ? '\n' : '')); - } - - protected nonFormCommands: (symbol | Commands.CommandType)[] = [ - Commands.CommandType.AutosenseLabelDimensionsCommand, - Commands.CommandType.PrintConfigurationCommand, - Commands.CommandType.RawDocumentCommand, - Commands.CommandType.RebootPrinterCommand, - Commands.CommandType.SetDarknessCommand - ]; - - protected transpileCommandMap = new Map< - symbol | Commands.CommandType, - TranspileCommandDelegate - >([ - /* eslint-disable prettier/prettier */ - // Ghost commands which shouldn't make it this far. - [Commands.CommandType.NewLabelCommand, this.unprocessedCommand], - [Commands.CommandType.CommandCustomSpecificCommand, this.unprocessedCommand], - [Commands.CommandType.CommandLanguageSpecificCommand, this.unprocessedCommand], - // Actually valid commands to parse - [Commands.CommandType.OffsetCommand, this.modifyOffset], + private encoder = new TextEncoder(); + + get commandLanguage(): Options.PrinterCommandLanguage { + return Options.PrinterCommandLanguage.zpl; + } + + get formStartCommand(): Uint8Array { + // All ZPL documents start with the start-of-document command. + return this.encodeCommand('\n^XA\n'); + } + + get formEndCommand(): Uint8Array { + // All ZPL documents end with the end-of-document command. + return this.encodeCommand('\n^XZ\n'); + } + + encodeCommand(str = '', withNewline = true): Uint8Array { + // TODO: ZPL supports omitting the newline, figure out a clever way to + // handle situations where newlines are optional to reduce line noise. + return this.encoder.encode(str + (withNewline ? '\n' : '')); + } + + protected nonFormCommands: (symbol | Commands.CommandType)[] = [ + 'AutosenseLabelDimensionsCommand', + 'PrintConfigurationCommand', + 'RawDocumentCommand', + 'RebootPrinterCommand', + 'SetDarknessCommand' + ]; + + constructor( + extendedCommands: Array> = [] + ) { + super(Options.PrinterCommandLanguage.zpl, extendedCommands); + } + + public transpileCommand( + cmd: Commands.IPrinterCommand, + docState: TranspiledDocumentState + ): Uint8Array { + switch (cmd.type) { + default: + exhaustiveMatchGuard(cmd.type); + break; + case 'CustomCommand': + return this.extendedCommandHandler(cmd, docState); + case 'NewLabelCommand': + // Should have been compiled out at a higher step. + return this.unprocessedCommand(cmd); + + case 'RebootPrinterCommand': + return this.encodeCommand('~JR'); + case 'QueryConfigurationCommand': + return this.encodeCommand('^HZA\r\n^HH'); + case 'PrintConfigurationCommand': + return this.encodeCommand('~WC'); + case 'SaveCurrentConfigurationCommand': + return this.encodeCommand('^JUS'); + + case 'SetPrintDirectionCommand': + return this.setPrintDirectionCommand((cmd as Commands.SetPrintDirectionCommand).upsideDown); + case 'SetDarknessCommand': + return this.setDarknessCommand((cmd as Commands.SetDarknessCommand).darknessSetting); + case 'AutosenseLabelDimensionsCommand': + return this.encodeCommand('~JC'); + case 'SetPrintSpeedCommand': + return this.setPrintSpeedCommand(cmd as Commands.SetPrintSpeedCommand); + case 'SetLabelDimensionsCommand': + return this.setLabelDimensionsCommand(cmd as Commands.SetLabelDimensionsCommand); + case 'SetLabelHomeCommand': + return this.setLabelHomeCommand(cmd as Commands.SetLabelHomeCommand); + case 'SetLabelPrintOriginOffsetCommand': + return this.setLabelPrintOriginOffsetCommand(cmd as Commands.SetLabelPrintOriginOffsetCommand); + case 'SetLabelToContinuousMediaCommand': + return this.setLabelToContinuousMediaCommand(cmd as Commands.SetLabelToContinuousMediaCommand); + case 'SetLabelToMarkMediaCommand': + return this.setLabelToMarkMediaCommand(cmd as Commands.SetLabelToMarkMediaCommand); + case 'SetLabelToWebGapMediaCommand': + return this.setLabelToWebGapMediaCommand(cmd as Commands.SetLabelToWebGapMediaCommand); + + case 'ClearImageBufferCommand': // Clear image buffer isn't a relevant command on ZPL printers. // Closest equivalent is the ~JP (pause and cancel) or ~JA (cancel all) but both // affect in-progress printing operations which is unlikely to be desired operation. // Translate as a no-op. - [Commands.CommandType.ClearImageBufferCommand, () => this.noop], - // ZPL doens't have an OOTB cut command except for one printer. - // Cutter behavior should be managed by the ^MM command instead. - [Commands.CommandType.CutNowCommand, () => this.noop], + return this.noop; + case 'SuppressFeedBackupCommand': // ZPL needs this for every form printed. - [Commands.CommandType.SuppressFeedBackupCommand, () => this.encodeCommand('^XB')], + return this.encodeCommand('^XB'); + case 'EnableFeedBackupCommand': // ZPL doesn't have an enable, it just expects XB for every label // that should not back up. - [Commands.CommandType.EnableFeedBackupCommand, () => this.noop], - [Commands.CommandType.RebootPrinterCommand, () => this.encodeCommand('~JR')], - // HH returns serial as raw text, HZA gets everything but the serial in XML. - [Commands.CommandType.QueryConfigurationCommand, () => this.encodeCommand('^HZA\r\n^HH')], - [Commands.CommandType.PrintConfigurationCommand, () => this.encodeCommand('~WC')], - [Commands.CommandType.SaveCurrentConfigurationCommand, () => this.encodeCommand('^JUS')], - [Commands.CommandType.SetPrintDirectionCommand, this.setPrintDirectionCommand], - [Commands.CommandType.SetDarknessCommand, this.setDarknessCommand], - [Commands.CommandType.SetPrintSpeedCommand, this.setPrintSpeedCommand], - [Commands.CommandType.AutosenseLabelDimensionsCommand, () => this.encodeCommand('~JC')], - [Commands.CommandType.SetLabelDimensionsCommand, this.setLabelDimensionsCommand], - [Commands.CommandType.SetLabelHomeCommand, this.setLabelHomeCommand], - [Commands.CommandType.SetLabelPrintOriginOffsetCommand, this.setLabelPrintOriginOffsetCommand], - [Commands.CommandType.SetLabelToContinuousMediaCommand, this.setLabelToContinuousMediaCommand], - [Commands.CommandType.SetLabelToWebGapMediaCommand, this.setLabelToWebGapMediaCommand], - [Commands.CommandType.SetLabelToMarkMediaCommand, this.setLabelToMarkMediaCommand], - [Commands.CommandType.AddImageCommand, this.addImageCommand], - [Commands.CommandType.AddLineCommand, this.addLineCommand], - [Commands.CommandType.AddBoxCommand, this.addBoxCommand], - [Commands.CommandType.PrintCommand, this.printCommand] - /* eslint-enable prettier/prettier */ - ]); - - constructor( - customCommands: Array<{ - commandType: symbol; - applicableLanguages: Options.PrinterCommandLanguage; - transpileDelegate: TranspileCommandDelegate; - commandInclusionMode: CommandFormInclusionMode; - }> = [] - ) { - super(); - - for (const newCmd of customCommands) { - if ((newCmd.applicableLanguages & this.commandLanguage) !== this.commandLanguage) { - // Command declared to not be applicable to this command set, skip it. - continue; - } - - this.transpileCommandMap.set(newCmd.commandType, newCmd.transpileDelegate); - if (newCmd.commandInclusionMode !== CommandFormInclusionMode.sharedForm) { - this.nonFormCommands.push(newCmd.commandType); - } - } - } - - parseConfigurationResponse( - rawText: string, - commOpts: PrinterCommunicationOptions - ): Options.PrinterOptions { - if (rawText.length <= 0) { - return Options.PrinterOptions.invalid(); - } - - // The two commands run were ^HH to get the raw two-column config label, and ^HZA to get the - // full XML configuration block. Unfortunately ZPL doesn't seem to put the serial number in - // the XML so we must pull it from the first line of the raw two-column config. - - // Fascinatingly, it doesn't matter what order the two commands appear in. The XML will be - // presented first and the raw label afterwards. - const pivotText = '\r\n'; - const pivot = rawText.lastIndexOf(pivotText) + pivotText.length; - if (pivot == pivotText.length - 1) { - return Options.PrinterOptions.invalid(); - } - - const rawConfig = rawText.substring(pivot); - // First line of the raw config should be the serial, which should be alphanumeric. - const serial = rawConfig.match(/[A-Z0-9]+/i)[0]; - - // ZPL configuration is just XML, parse it into an object and then into config. - - // For reasons I do not understand printers will tend to send _one_ invalid XML line - // and it looks like - // ` ENUM='NONE, AUTO DETECT, TAG-IT, ICODE, PICO, ISO15693, EPC, UID'>` - // This is supposed to look like - // `` - // I don't have the appropriate equipment to determine where the XML tag prefix is being - // lost. Do a basic find + replace to replace an instance of the exact text with a fixed - // version instead. - // TODO: Deeper investigation with more printers? - const xmlStart = rawText.indexOf(""); - const rawXml = rawText - .substring(xmlStart, pivot) - .replace( - "\n ENUM='NONE, AUTO DETECT, TAG-IT, ICODE, PICO, ISO15693, EPC, UID'>", - "" - ); - - // The rest is straightforward: parse it as an XML document and pull out - // the data. The format is standardized and semi-self-documenting. - const parser = new DOMParser(); - const xmldoc = parser.parseFromString(rawXml, 'application/xml'); - const errorNode = xmldoc.querySelector('parsererror'); - if (errorNode) { - // TODO: Log? Throw? - return Options.PrinterOptions.invalid(); - } - - return this.docToOptions(xmldoc, serial, commOpts); - } - - private docToOptions( - doc: Document, - serial: string, - commOpts: PrinterCommunicationOptions - ): Options.PrinterOptions { - // ZPL includes enough information in the document to autodetect the printer's capabilities. - const rawModel = this.getXmlText(doc, 'MODEL'); - let model: PrinterModel | string = PrinterModelDb.getModel(rawModel); - if (model == PrinterModel.unknown) { - // If the database doesn't have this one listed just use the raw name. - model = rawModel; - } - // ZPL rounds, multiplying by 25 gets us to 'inches' in their book. - // 8 DPM == 200 DPI, for example. - const dpi = parseInt(this.getXmlText(doc, 'DOTS-PER-MM')) * 25; - // Max darkness is an attribute on the element - const maxDarkness = parseInt( - doc.getElementsByTagName('MEDIA-DARKNESS')[0].getAttribute('MAX').valueOf() - ); - - // Speed table is specially constructed with a few rules. - // Each table should have at least an auto, min, and max value. We assume we can use the whole - // number speeds between the min and max values. If the min and max values are the same though - // that indicates a mobile printer. - const printSpeedElement = doc.getElementsByTagName('PRINT-RATE')[0]; - const slewSpeedElement = doc.getElementsByTagName('SLEW-RATE')[0]; - // Highest minimum wins - const printMin = parseInt(printSpeedElement.getAttribute('MIN').valueOf()); - const slewMin = parseInt(slewSpeedElement.getAttribute('MIN').valueOf()); - const speedMin = printMin >= slewMin ? printMin : slewMin; - const printMax = parseInt(printSpeedElement.getAttribute('MAX').valueOf()); - const slewMax = parseInt(slewSpeedElement.getAttribute('MAX').valueOf()); - const speedMax = printMax <= slewMax ? printMax : slewMax; - - const modelInfo = new AutodetectedPrinter( - Options.PrinterCommandLanguage.zpl, - dpi, - model, - this.getSpeedTable(speedMin, speedMax), - maxDarkness - ); - - const options = new Options.PrinterOptions( - serial, - modelInfo, - this.getXmlText(doc, 'FIRMWARE-VERSION') - ); - - const currentDarkness = parseInt(this.getXmlCurrent(doc, 'MEDIA-DARKNESS')); - const rawDarkness = Math.ceil(currentDarkness * (100 / maxDarkness)); - options.darknessPercent = Math.max(0, Math.min(rawDarkness, 99)) as Options.DarknessPercent; - - const printRate = parseInt(this.getXmlText(doc, 'PRINT-RATE')); - const slewRate = parseInt(this.getXmlText(doc, 'SLEW-RATE')); - options.speed = new Options.PrintSpeedSettings( - Options.PrintSpeedSettings.getSpeedFromWholeNumber(printRate), - Options.PrintSpeedSettings.getSpeedFromWholeNumber(slewRate) - ); - - // Always in dots - const labelWidth = parseInt(this.getXmlCurrent(doc, 'PRINT-WIDTH')); - const labelLength = parseInt(this.getXmlText(doc, 'LABEL-LENGTH')); - const labelRoundingStep = commOpts.labelDimensionRoundingStep ?? 0; - if (labelRoundingStep > 0) { - // Label size should be rounded to the step value by round-tripping the value to an inch - // then rounding, then back to dots. - const roundedWidth = this.roundToNearestStep( - labelWidth / options.model.dpi, - labelRoundingStep - ); - options.labelWidthDots = roundedWidth * options.model.dpi; - const roundedHeight = this.roundToNearestStep( - labelLength / options.model.dpi, - labelRoundingStep - ); - options.labelHeightDots = roundedHeight * options.model.dpi; - } else { - // No rounding - options.labelWidthDots = labelWidth; - options.labelHeightDots = labelLength; - } - - // Some firmware versions let you store this, some only retain while power is on. - const labelHorizontalOffset = parseInt(this.getXmlText(doc, 'LABEL-SHIFT')) || 0; - const labelHeightOffset = parseInt(this.getXmlCurrent(doc, 'LABEL-TOP')) || 0; - options.labelPrintOriginOffsetDots = { - left: labelHorizontalOffset, - top: labelHeightOffset - }; - - options.printOrientation = - this.getXmlText(doc, 'LABEL-REVERSE') === 'Y' - ? Options.PrintOrientation.inverted - : Options.PrintOrientation.normal; - - options.thermalPrintMode = - this.getXmlCurrent(doc, 'MEDIA-TYPE') === 'DIRECT-THERMAL' - ? Options.ThermalPrintMode.direct - : Options.ThermalPrintMode.transfer; - - options.mediaPrintMode = this.parsePrintMode(this.getXmlCurrent(doc, 'PRINT-MODE')); - - options.labelGapDetectMode = this.parseMediaType(this.getXmlCurrent(doc, 'MEDIA-TRACKING')); - - options.mediaPrintMode = - this.getXmlCurrent(doc, 'PRE-PEEL') === 'Y' - ? Options.MediaPrintMode.peelWithPrepeel - : options.mediaPrintMode; - - // TODO: more hardware options: - // - Figure out how to encode C{num} for cut-after-label-count - - // TODO other options: - // Autosense settings? - // Character set? - // Error handling? - // Continuous media? - // Black mark printing? - // Media feed on powerup settings? - // Prepeel rewind? - - return options; - } - - private range(start: number, stop: number, step = 1) { - return Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step); - } - - private getXmlText(doc: Document, tag: string) { - return doc.getElementsByTagName(tag)[0].textContent; - } - - private getXmlCurrent(doc: Document, tag: string) { - return doc.getElementsByTagName(tag)[0].getElementsByTagName('CURRENT')[0].textContent; - } - - private parsePrintMode(str: string) { - switch (str) { - case 'REWIND': - return Options.MediaPrintMode.rewind; - case 'PEEL OFF': - return Options.MediaPrintMode.peel; - case 'CUTTER': - return Options.MediaPrintMode.cutter; - default: - case 'TEAR OFF': - return Options.MediaPrintMode.tearoff; - } - } - - private parseMediaType(str: string) { - switch (str) { - case 'CONTINUOUS': - return Options.LabelMediaGapDetectionMode.continuous; - case 'NONCONT-MARK': - return Options.LabelMediaGapDetectionMode.markSensing; - default: - case 'NONCONT-WEB': - return Options.LabelMediaGapDetectionMode.webSensing; - } - } - - private getSpeedTable(min: number, max: number) { - const table = new Map([ - [Options.PrintSpeed.ipsAuto, 0], - [Options.PrintSpeed.ipsPrinterMin, min], - [Options.PrintSpeed.ipsPrinterMax, max] - ]); - this.range(min, max).forEach((s) => - table.set(Options.PrintSpeedSettings.getSpeedFromWholeNumber(s), s) - ); - return table; - } - - private getFieldOffsetCommand( - formMetadata: TranspilationFormMetadata, - additionalHorizontal = 0, - additionalVertical = 0 - ) { - const xOffset = Math.trunc(formMetadata.horizontalOffset + additionalHorizontal); - const yOffset = Math.trunc(formMetadata.verticalOffset + additionalVertical); - return `^FO${xOffset},${yOffset}`; - } - - private addImageCommand( - cmd: Commands.AddImageCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - if (cmd?.bitmap == null) { - return cmdSet.noop; - } - - // ZPL inverts colors. 1 means black, 0 means white. I don't know why. - const bitmap = cmd.bitmap.toInvertedGRF(); - - // ZPL supports compressed binary on pretty much all firmwares, default to that. - // TODO: ASCII-compressed formats are only supported on newer firmwares. - // Implement feature detection into the transpiler operation to choose the most - // appropriate compression format such as LZ77/DEFLATE compression for Z64. - const buffer = bitmap.toZebraCompressedGRF(); - - // Because the image may be trimmed add an offset command to position to the image data. - const fieldStart = cmdSet.getFieldOffsetCommand( - outDoc, - bitmap.boundingBox.paddingLeft, - bitmap.boundingBox.paddingTop - ); - - const byteLen = bitmap.bytesUncompressed; - const graphicCmd = `^GFA,${byteLen},${byteLen},${bitmap.bytesPerRow},${buffer}`; - - const fieldEnd = '^FS'; - - // Finally, bump the document offset according to the image height. - outDoc.verticalOffset += bitmap.boundingBox.height; - - return cmdSet.encodeCommand(fieldStart + graphicCmd + fieldEnd); - } + return this.noop; + + case 'OffsetCommand': + return this.modifyOffset(cmd as Commands.OffsetCommand, docState, this); + case 'RawDocumentCommand': + return this.encodeCommand((cmd as Commands.RawDocumentCommand).rawDocument, false); + case 'AddBoxCommand': + return this.addBoxCommand(cmd as Commands.AddBoxCommand, docState); + case 'AddImageCommand': + return this.addImageCommand(cmd as Commands.AddImageCommand, docState); + case 'AddLineCommand': + return this.addLineCommand(cmd as Commands.AddLineCommand, docState); + case 'CutNowCommand': + // ZPL doesn't have an OOTB cut command except for one printer. + // Cutter behavior should be managed by the ^MM command instead. + return this.noop; - private setPrintDirectionCommand( - cmd: Commands.SetPrintDirectionCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const dir = cmd.upsideDown ? 'I' : 'N'; - return cmdSet.encodeCommand(`^PO${dir}`); + case 'PrintCommand': + return this.printCommand(cmd as Commands.PrintCommand); } - - private setDarknessCommand( - cmd: Commands.SetDarknessCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const dark = Math.trunc(cmd.darknessSetting); - return cmdSet.encodeCommand(`~SD${dark}`); + } + + parseConfigurationResponse( + rawText: string, + mediaOptions: Options.IPrinterLabelMediaOptions, + ): Options.PrinterOptions { + if (rawText.length <= 0) { + return Options.PrinterOptions.invalid; } - private setPrintSpeedCommand( - cmd: Commands.SetPrintSpeedCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - // ZPL uses separate print, slew, and backfeed speeds. Re-use print for backfeed. - return cmdSet.encodeCommand(`^PR${cmd.speedVal},${cmd.mediaSpeedVal},${cmd.speedVal}`); - } + // The two commands run were ^HH to get the raw two-column config label, and ^HZA to get the + // full XML configuration block. Unfortunately ZPL doesn't seem to put the serial number in + // the XML so we must pull it from the first line of the raw two-column config. - private setLabelDimensionsCommand( - cmd: Commands.SetLabelDimensionsCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const width = Math.trunc(cmd.widthInDots); - const widthCmd = cmdSet.encodeCommand(`^PW${width}`); - if (cmd.setsHeight) { - const height = Math.trunc(cmd.heightInDots); - const heightCmd = cmdSet.encodeCommand(`^LL${height},N`); - return cmdSet.combineCommands(widthCmd, heightCmd); - } - return widthCmd; + // Fascinatingly, it doesn't matter what order the two commands appear in. The XML will be + // presented first and the raw label afterwards. + const pivotText = '\r\n'; + const pivot = rawText.lastIndexOf(pivotText) + pivotText.length; + if (pivot == pivotText.length - 1) { + return Options.PrinterOptions.invalid; } - private setLabelHomeCommand( - cmd: Commands.SetLabelHomeCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const xOffset = Math.trunc(cmd.xOffset); - const yOffset = Math.trunc(cmd.yOffset); - return cmdSet.encodeCommand(`^LH${xOffset},${yOffset}`); + const rawConfig = rawText.substring(pivot); + // First line of the raw config should be the serial, which should be alphanumeric. + const serial = rawConfig.match(/[A-Z0-9]+/i)?.at(0) ?? 'no_serial_nm'; + + // ZPL configuration is just XML, parse it into an object and then into config. + + // For reasons I do not understand printers will tend to send _one_ invalid XML line + // and it looks like + // ` ENUM='NONE, AUTO DETECT, TAG-IT, ICODE, PICO, ISO15693, EPC, UID'>` + // This is supposed to look like + // `` + // I don't have the appropriate equipment to determine where the XML tag prefix is being + // lost. Do a basic find + replace to replace an instance of the exact text with a fixed + // version instead. + // TODO: Deeper investigation with more printers? + const xmlStart = rawText.indexOf(""); + const rawXml = rawText + .substring(xmlStart, pivot) + .replace( + "\n ENUM='NONE, AUTO DETECT, TAG-IT, ICODE, PICO, ISO15693, EPC, UID'>", + "" + ); + + // The rest is straightforward: parse it as an XML document and pull out + // the data. The format is standardized and semi-self-documenting. + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(rawXml, 'application/xml'); + const errorNode = xmlDoc.querySelector('parsererror'); + if (errorNode) { + // TODO: Log? Throw? + return Options.PrinterOptions.invalid; } - private setLabelPrintOriginOffsetCommand( - cmd: Commands.SetLabelPrintOriginOffsetCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - // This ends up being two commands, one to set the top and one to set the - // horizontal shift. LS moves the horizontal, LT moves the top. LT is - // clamped to +/- 120 dots, horizontal is 9999. - const xOffset = cmdSet.clampToRange(Math.trunc(cmd.xOffset), -9999, 9999); - const yOffset = cmdSet.clampToRange(Math.trunc(cmd.yOffset), -120, 120); - return cmdSet.encodeCommand(`^LS${xOffset}^LT${yOffset}`); + return this.docToOptions(xmlDoc, serial, mediaOptions); + } + + private docToOptions( + doc: Document, + serial: string, + mediaOptions: Options.IPrinterLabelMediaOptions + ): Options.PrinterOptions { + // ZPL includes enough information in the document to autodetect the printer's capabilities. + const rawModel = this.getXmlText(doc, 'MODEL') ?? 'UNKNOWN_ZPL'; + const model = PrinterModelDb.getModel(rawModel); + + // ZPL rounds, multiplying by 25 gets us to 'inches' in their book. + // 8 DPM == 200 DPI, for example. + const dpi = parseInt(this.getXmlText(doc, 'DOTS-PER-MM') ?? '8') * 25; + // Max darkness is an attribute on the element + const maxDarkness = parseInt( + doc.getElementsByTagName('MEDIA-DARKNESS').item(0)?.getAttribute('MAX')?.valueOf() ?? '30' + ); + + // Speed table is specially constructed with a few rules. + // Each table should have at least an auto, min, and max value. We assume we can use the whole + // number speeds between the min and max values. If the min and max values are the same though + // that indicates a mobile printer. + const printSpeedElement = doc.getElementsByTagName('PRINT-RATE').item(0); + const slewSpeedElement = doc.getElementsByTagName('SLEW-RATE').item(0); + const speedDefault = '0'; + // Highest minimum wins + const printMin = parseInt(printSpeedElement?.getAttribute('MIN')?.valueOf() ?? speedDefault); + const slewMin = parseInt(slewSpeedElement?.getAttribute('MIN')?.valueOf() ?? speedDefault); + const speedMin = printMin >= slewMin ? printMin : slewMin; + // Lowest max wins + const printMax = parseInt(printSpeedElement?.getAttribute('MAX')?.valueOf() ?? speedDefault); + const slewMax = parseInt(slewSpeedElement?.getAttribute('MAX')?.valueOf() ?? speedDefault); + const speedMax = printMax <= slewMax ? printMax : slewMax; + + const modelInfo = new AutodetectedPrinter( + Options.PrinterCommandLanguage.zpl, + dpi, + model === PrinterModel.unknown ? rawModel : model, + this.getSpeedTable(speedMin, speedMax), + maxDarkness + ); + + const options = new Options.PrinterOptions( + serial, + modelInfo, + this.getXmlText(doc, 'FIRMWARE-VERSION') ?? '' + ); + + const currentDarkness = parseInt(this.getXmlCurrent(doc, 'MEDIA-DARKNESS') ?? '15'); + const rawDarkness = Math.ceil(currentDarkness * (100 / maxDarkness)); + options.darknessPercent = Math.max(0, Math.min(rawDarkness, 99)) as Options.DarknessPercent; + + const printRate = parseInt(this.getXmlText(doc, 'PRINT-RATE') ?? '1'); + const slewRate = parseInt(this.getXmlText(doc, 'SLEW-RATE') ?? '1'); + options.speed = new Options.PrintSpeedSettings( + Options.PrintSpeedSettings.getSpeedFromWholeNumber(printRate), + Options.PrintSpeedSettings.getSpeedFromWholeNumber(slewRate) + ); + + // Always in dots + const labelWidth = parseInt(this.getXmlCurrent(doc, 'PRINT-WIDTH') ?? '200'); + const labelLength = parseInt(this.getXmlText(doc, 'LABEL-LENGTH') ?? '200'); + const labelRoundingStep = mediaOptions.labelDimensionRoundingStep ?? 0; + if (labelRoundingStep > 0) { + // Label size should be rounded to the step value by round-tripping the value to an inch + // then rounding, then back to dots. + const roundedWidth = this.roundToNearestStep( + labelWidth / options.model.dpi, + labelRoundingStep + ); + options.labelWidthDots = roundedWidth * options.model.dpi; + const roundedHeight = this.roundToNearestStep( + labelLength / options.model.dpi, + labelRoundingStep + ); + options.labelHeightDots = roundedHeight * options.model.dpi; + } else { + // No rounding + options.labelWidthDots = labelWidth; + options.labelHeightDots = labelLength; } - private setLabelToContinuousMediaCommand( - cmd: Commands.SetLabelToContinuousMediaCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.labelLengthInDots); - const gap = Math.trunc(cmd.labelGapInDots); - return cmdSet.encodeCommand(`^MNN^LL${length + gap}`); + // Some firmware versions let you store this, some only retain while power is on. + const labelHorizontalOffset = parseInt(this.getXmlText(doc, 'LABEL-SHIFT') ?? '0') || 0; + const labelHeightOffset = parseInt(this.getXmlCurrent(doc, 'LABEL-TOP') ?? '0') || 0; + options.labelPrintOriginOffsetDots = { + left: labelHorizontalOffset, + top: labelHeightOffset + }; + + options.printOrientation = + this.getXmlText(doc, 'LABEL-REVERSE') === 'Y' + ? Options.PrintOrientation.inverted + : Options.PrintOrientation.normal; + + options.thermalPrintMode = + this.getXmlCurrent(doc, 'MEDIA-TYPE') === 'DIRECT-THERMAL' + ? Options.ThermalPrintMode.direct + : Options.ThermalPrintMode.transfer; + + options.mediaPrintMode = this.parsePrintMode(this.getXmlCurrent(doc, 'PRINT-MODE') ?? ''); + + options.labelGapDetectMode = this.parseMediaType(this.getXmlCurrent(doc, 'MEDIA-TRACKING') ?? ''); + + options.mediaPrintMode = + this.getXmlCurrent(doc, 'PRE-PEEL') === 'Y' + ? Options.MediaPrintMode.peelWithPrePeel + : options.mediaPrintMode; + + // TODO: more hardware options: + // - Figure out how to encode C{num} for cut-after-label-count + + // TODO other options: + // Autosense settings? + // Character set? + // Error handling? + // Continuous media? + // Black mark printing? + // Media feed on power up settings? + // Pre-peel rewind? + + return options; + } + + private range(start: number, stop: number, step = 1) { + return Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step); + } + + private getXmlText(doc: Document, tag: string) { + return doc.getElementsByTagName(tag).item(0)?.textContent ?? undefined; + } + + private getXmlCurrent(doc: Document, tag: string) { + return doc.getElementsByTagName(tag).item(0) + ?.getElementsByTagName('CURRENT').item(0) + ?.textContent ?? undefined; + } + + private parsePrintMode(str: string) { + switch (str) { + case 'REWIND': + return Options.MediaPrintMode.rewind; + case 'PEEL OFF': + return Options.MediaPrintMode.peel; + case 'CUTTER': + return Options.MediaPrintMode.cutter; + default: + case 'TEAR OFF': + return Options.MediaPrintMode.tearOff; } - - private setLabelToWebGapMediaCommand( - cmd: Commands.SetLabelToWebGapMediaCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.labelLengthInDots); - return cmdSet.encodeCommand(`^MNY^LL${length},Y`); - } - - private setLabelToMarkMediaCommand( - cmd: Commands.SetLabelToMarkMediaCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - const length = Math.trunc(cmd.labelLengthInDots); - const lineOffset = Math.trunc(cmd.blackLineOffset); - return cmdSet.encodeCommand(`^MNM,${length}^LL${lineOffset}`); + } + + private parseMediaType(str: string) { + switch (str) { + case 'CONTINUOUS': + return Options.LabelMediaGapDetectionMode.continuous; + case 'NONCONT-MARK': + return Options.LabelMediaGapDetectionMode.markSensing; + default: + case 'NONCONT-WEB': + return Options.LabelMediaGapDetectionMode.webSensing; } - - private printCommand( - cmd: Commands.PrintCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - // TODO: Make sure this actually works this way.. - // According to the docs the first parameter is "total" labels, - // while the third is duplicates. - const total = Math.trunc(cmd.count * (cmd.additionalDuplicateOfEach + 1)); - const dup = Math.trunc(cmd.additionalDuplicateOfEach); - return cmdSet.encodeCommand(`^PQ${total},0,${dup},N`); - } - - private addLineCommand( - cmd: Commands.AddLineCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - return cmdSet.lineOrBoxToCmd( - cmdSet, - outDoc, - cmd.heightInDots, - cmd.lengthInDots, - cmd.color, - // A line is just a box filled in! - Math.min(cmd.heightInDots, cmd.lengthInDots) - ); + } + + private getSpeedTable(min: number, max: number) { + return new Map([ + [Options.PrintSpeed.ipsAuto, 0], + [Options.PrintSpeed.ipsPrinterMin, min], + [Options.PrintSpeed.ipsPrinterMax, max], + ...this.range(min, max).map(s => + [Options.PrintSpeedSettings.getSpeedFromWholeNumber(s), s] as [Options.PrintSpeed, number]) + ]); + } + + private getFieldOffsetCommand( + formMetadata: TranspiledDocumentState, + additionalHorizontal = 0, + additionalVertical = 0 + ) { + const xOffset = Math.trunc(formMetadata.horizontalOffset + additionalHorizontal); + const yOffset = Math.trunc(formMetadata.verticalOffset + additionalVertical); + return `^FO${xOffset},${yOffset}`; + } + + private addImageCommand( + cmd: Commands.AddImageCommand, + outDoc: TranspiledDocumentState + ): Uint8Array { + // ZPL treats colors as print element enable. 1 means black, 0 means white. + const bitmap = cmd.bitmap; + // TODO: support image conversion options. + //const imageOptions = cmd.imageConversionOptions; + + // ZPL supports compressed binary on pretty much all firmware, default to that. + // TODO: ASCII-compressed formats are only supported on newer firmware. + // Implement feature detection into the transpiler operation to choose the most + // appropriate compression format such as LZ77/DEFLATE compression for Z64. + const buffer = bitmap.toZebraCompressedGRF(); + + // Because the image may be trimmed add an offset command to position to the image data. + const fieldStart = this.getFieldOffsetCommand( + outDoc, + bitmap.boundingBox.paddingLeft, + bitmap.boundingBox.paddingTop + ); + + const byteLen = bitmap.bytesUncompressed; + const graphicCmd = `^GFA,${byteLen},${byteLen},${bitmap.bytesPerRow},${buffer}`; + + const fieldEnd = '^FS'; + + // Finally, bump the document offset according to the image height. + outDoc.verticalOffset += bitmap.boundingBox.height; + + return this.encodeCommand(fieldStart + graphicCmd + fieldEnd); + } + + private setPrintDirectionCommand( + upsideDown: boolean + ): Uint8Array { + const dir = upsideDown ? 'I' : 'N'; + return this.encodeCommand(`^PO${dir}`); + } + + private setDarknessCommand( + darkness: number + ): Uint8Array { + const dark = Math.trunc(darkness); + return this.encodeCommand(`~SD${dark}`); + } + + private setPrintSpeedCommand( + cmd: Commands.SetPrintSpeedCommand, + ): Uint8Array { + // ZPL uses separate print, slew, and backfeed speeds. Re-use print for backfeed. + return this.encodeCommand(`^PR${cmd.speedVal},${cmd.mediaSpeedVal},${cmd.speedVal}`); + } + + private setLabelDimensionsCommand( + cmd: Commands.SetLabelDimensionsCommand + ): Uint8Array { + const width = Math.trunc(cmd.widthInDots); + const widthCmd = this.encodeCommand(`^PW${width}`); + if (cmd.setsHeight && cmd.heightInDots !== undefined && cmd.gapLengthInDots !== undefined) { + const height = Math.trunc(cmd.heightInDots); + const heightCmd = this.encodeCommand(`^LL${height},N`); + return this.combineCommands(widthCmd, heightCmd); } - - private addBoxCommand( - cmd: Commands.AddBoxCommand, - outDoc: TranspilationFormMetadata, - cmdSet: ZplPrinterCommandSet - ): Uint8Array { - return cmdSet.lineOrBoxToCmd( - cmdSet, - outDoc, - cmd.heightInDots, - cmd.lengthInDots, - Commands.DrawColor.black, - cmd.thickness - ); + return widthCmd; + } + + private setLabelHomeCommand( + cmd: Commands.SetLabelHomeCommand + ): Uint8Array { + const xOffset = Math.trunc(cmd.xOffset); + const yOffset = Math.trunc(cmd.yOffset); + return this.encodeCommand(`^LH${xOffset},${yOffset}`); + } + + private setLabelPrintOriginOffsetCommand( + cmd: Commands.SetLabelPrintOriginOffsetCommand + ): Uint8Array { + // This ends up being two commands, one to set the top and one to set the + // horizontal shift. LS moves the horizontal, LT moves the top. LT is + // clamped to +/- 120 dots, horizontal is 9999. + const xOffset = clampToRange(Math.trunc(cmd.xOffset), -9999, 9999); + const yOffset = clampToRange(Math.trunc(cmd.yOffset), -120, 120); + return this.encodeCommand(`^LS${xOffset}^LT${yOffset}`); + } + + private setLabelToContinuousMediaCommand( + cmd: Commands.SetLabelToContinuousMediaCommand + ): Uint8Array { + const length = Math.trunc(cmd.labelLengthInDots); + const gap = Math.trunc(cmd.labelGapInDots); + return this.encodeCommand(`^MNN^LL${length + gap}`); + } + + private setLabelToWebGapMediaCommand( + cmd: Commands.SetLabelToWebGapMediaCommand + ): Uint8Array { + const length = Math.trunc(cmd.labelLengthInDots); + return this.encodeCommand(`^MNY^LL${length},Y`); + } + + private setLabelToMarkMediaCommand( + cmd: Commands.SetLabelToMarkMediaCommand + ): Uint8Array { + const length = Math.trunc(cmd.labelLengthInDots); + const lineOffset = Math.trunc(cmd.blackLineOffset); + return this.encodeCommand(`^MNM,${length}^LL${lineOffset}`); + } + + private printCommand( + cmd: Commands.PrintCommand + ): Uint8Array { + // TODO: Make sure this actually works this way.. + // According to the docs the first parameter is "total" labels, + // while the third is duplicates. + const total = Math.trunc(cmd.count * (cmd.additionalDuplicateOfEach + 1)); + const dup = Math.trunc(cmd.additionalDuplicateOfEach); + return this.encodeCommand(`^PQ${total},0,${dup},N`); + } + + private addLineCommand( + cmd: Commands.AddLineCommand, + outDoc: TranspiledDocumentState + ): Uint8Array { + return this.lineOrBoxToCmd( + outDoc, + cmd.heightInDots, + cmd.lengthInDots, + cmd.color, + // A line is just a box filled in! + Math.min(cmd.heightInDots, cmd.lengthInDots) + ); + } + + private addBoxCommand( + cmd: Commands.AddBoxCommand, + outDoc: TranspiledDocumentState, + ): Uint8Array { + return this.lineOrBoxToCmd( + outDoc, + cmd.heightInDots, + cmd.lengthInDots, + Commands.DrawColor.black, + cmd.thickness + ); + } + + private lineOrBoxToCmd( + outDoc: TranspiledDocumentState, + height: number, + length: number, + color: Commands.DrawColor, + thickness?: number + ): Uint8Array { + height = Math.trunc(height) || 0; + thickness = Math.trunc(thickness ?? 1) || 1; + length = Math.trunc(length) || 0; + let drawMode: string; + switch (color) { + case Commands.DrawColor.black: + drawMode = 'B'; + break; + case Commands.DrawColor.white: + drawMode = 'W'; + break; } + const fieldStart = this.getFieldOffsetCommand(outDoc); - private lineOrBoxToCmd( - cmdSet: ZplPrinterCommandSet, - outDoc: TranspilationFormMetadata, - height: number, - length: number, - color: Commands.DrawColor, - thickness?: number - ): Uint8Array { - height = Math.trunc(height) || 0; - thickness = Math.trunc(thickness) || 1; - length = Math.trunc(length) || 0; - let drawMode: string; - switch (color) { - case Commands.DrawColor.black: - drawMode = 'B'; - break; - case Commands.DrawColor.white: - drawMode = 'W'; - break; - } - const fieldStart = cmdSet.getFieldOffsetCommand(outDoc); - - // TODO: Support rounding? - return cmdSet.encodeCommand( - [fieldStart, `^GB${length}`, height, thickness, drawMode, '^FS'].join(',') - ); - } + // TODO: Support rounding? + return this.encodeCommand( + [fieldStart, `^GB${length}`, height, thickness, drawMode, '^FS'].join(',') + ); + } } diff --git a/src/Printers/Models/EplPrinterModels.ts b/src/Printers/Models/EplPrinterModels.ts index 674026e..6eff466 100644 --- a/src/Printers/Models/EplPrinterModels.ts +++ b/src/Printers/Models/EplPrinterModels.ts @@ -3,57 +3,57 @@ import { PrinterCommandLanguage, PrintSpeed } from '../Configuration/PrinterOpti /** EPL printers have a lot in common. */ export abstract class EplPrinter extends BasePrinterInfo { - get commandLanguage(): PrinterCommandLanguage { - return PrinterCommandLanguage.epl; - } + get commandLanguage(): PrinterCommandLanguage { + return PrinterCommandLanguage.epl; + } - get maxDarkness(): number { - return 15; // EPL max darkness - } + get maxDarkness(): number { + return 15; // EPL max darkness + } } /** 28XX model printers are mostly the same */ export abstract class LP28XX extends EplPrinter { - get dpi(): number { - return 203; - } - - abstract get model(): PrinterModel; - - private _speedTable = new Map([ - [PrintSpeed.ipsAuto, 3], - [PrintSpeed.ipsPrinterMax, 4], - [PrintSpeed.ipsPrinterMin, 1], - [PrintSpeed.ips1_5, 1], - [PrintSpeed.ips2, 2], - [PrintSpeed.ips2_5, 3], - [PrintSpeed.ips3_5, 4] - ]); - get speedTable(): ReadonlyMap { - return this._speedTable; - } + get dpi(): number { + return 203; + } + + abstract get model(): PrinterModel; + + private _speedTable = new Map([ + [PrintSpeed.ipsAuto, 3], + [PrintSpeed.ipsPrinterMax, 4], + [PrintSpeed.ipsPrinterMin, 1], + [PrintSpeed.ips1_5, 1], + [PrintSpeed.ips2, 2], + [PrintSpeed.ips2_5, 3], + [PrintSpeed.ips3_5, 4] + ]); + get speedTable(): ReadonlyMap { + return this._speedTable; + } } export class LP2844 extends LP28XX { - get model() { - return PrinterModel.lp2824; - } + get model() { + return PrinterModel.lp2824; + } } export class LP2824 extends LP28XX { - get model() { - return PrinterModel.lp2824; - } + get model() { + return PrinterModel.lp2824; + } } export class TLP2824 extends LP28XX { - get model() { - return PrinterModel.tlp2824; - } + get model() { + return PrinterModel.tlp2824; + } } export class TLP2844 extends LP28XX { - get model() { - return PrinterModel.tlp2844; - } + get model() { + return PrinterModel.tlp2844; + } } diff --git a/src/Printers/Models/PrinterModel.ts b/src/Printers/Models/PrinterModel.ts index 23ad8ea..1080de6 100644 --- a/src/Printers/Models/PrinterModel.ts +++ b/src/Printers/Models/PrinterModel.ts @@ -2,153 +2,153 @@ import { WebZlpError } from '../../WebZlpError.js'; import { PrinterCommandLanguage, PrintSpeed } from '../Configuration/PrinterOptions.js'; export enum PrinterModel { - unknown = 'unknown', - zplAutodetect = 'ZPL_AUTODETECT', - lp2824 = 'LP2824', - lp2824z = 'LP2824Z', - lp2844 = 'LP2844', - lp2844ups = 'LP2844UPS', - lp2844fedex = 'LP2844FEDEX', - lp2844z = 'LP2844Z', - tlp2824 = 'TLP2824', - tlp2824z = 'TLP2824Z', - tlp2844 = 'TPL2844', - tlp2844z = 'TPL2844Z' + unknown = 'unknown', + zplAutodetect = 'ZPL_AUTODETECT', + lp2824 = 'LP2824', + lp2824z = 'LP2824Z', + lp2844 = 'LP2844', + lp2844ups = 'LP2844UPS', + lp2844fedex = 'LP2844FEDEX', + lp2844z = 'LP2844Z', + tlp2824 = 'TLP2824', + tlp2824z = 'TLP2824Z', + tlp2844 = 'TPL2844', + tlp2844z = 'TPL2844Z' } export interface IPrinterModelInfo { - /** Gets the command language for this printer. */ - get commandLanguage(): PrinterCommandLanguage; + /** Gets the command language for this printer. */ + get commandLanguage(): PrinterCommandLanguage; - /** Gets the DPI of this printer. */ - get dpi(): number; + /** Gets the DPI of this printer. */ + get dpi(): number; - /** Gets the model of this printer. */ - get model(): PrinterModel | string; + /** Gets the model of this printer. */ + get model(): PrinterModel | string; - /** Gets the map of speeds this printer supports. */ - get speedTable(): ReadonlyMap; + /** Gets the map of speeds this printer supports. */ + get speedTable(): ReadonlyMap; - /** Gets the max value of the darkness, to map to a percent. */ - get maxDarkness(): number; + /** Gets the max value of the darkness, to map to a percent. */ + get maxDarkness(): number; - /** Determine if a given speed will work with this model. */ - isSpeedValid(speed: PrintSpeed): boolean; + /** Determine if a given speed will work with this model. */ + isSpeedValid(speed: PrintSpeed): boolean; - /** Get the raw value this model understands as the speed. */ - getSpeedValue(speed: PrintSpeed): number | undefined; + /** Get the raw value this model understands as the speed. */ + getSpeedValue(speed: PrintSpeed): number; - /** Get a print speed for this printer for */ - fromRawSpeed(rawSpeed: number): PrintSpeed; + /** Get a print speed for this printer. Defaults to minimum. */ + fromRawSpeed(rawSpeed?: number): PrintSpeed; } export abstract class BasePrinterInfo implements IPrinterModelInfo { - /** Gets the command language for this printer. */ - abstract get commandLanguage(): PrinterCommandLanguage; - /** Gets the DPI of this printer. */ - abstract get dpi(): number; - /** Gets the model of this printer. */ - abstract get model(): PrinterModel | string; - - // Speed is determined by what the printer supports - // EPL printers have a table that determines their setting and it needs to be hardcoded. - // ZPL printers follow this pattern: - // 1 = 25.4 mm/sec. (1 inch/sec.) - // A or 2 = 50.8 mm/sec. (2 inches/sec.) - // A is the default print and backfeed speed - // B or 3 = 76.2 mm/sec. (3 inches/sec.) - // C or 4 = 101.6 mm/sec. (4 inches/sec.) - // 5 = 127 mm/sec. (5 inches/sec.) - // D or 6 = 152.4 mm/sec. (6 inches/sec.) - // D is the default media slew speed - // 7 = 177.8 mm/sec. (7 inches/sec.) - // E or 8 = 203.2 mm/sec. (8 inches/sec.) - // 9 = 220.5 mm/sec. (9 inches/sec.) - // 10 = 245 mm/sec. (10 inches/sec.) - // 11 = 269.5 mm/sec. (11 inches/sec.) - // 12 = 304.8 mm/sec. (12 inches/sec.) - // 13 = 13 in/sec - // 14 = 14 in/sec - // This gets encoded into the speed table. - // Every speed table should also have entries for ipsPrinterMin, ipsPrinterMax, and auto. - // These should be duplicate entries of real values in the speed table so that - // we have sane defaults for commands to default to. - /** Gets the map of speeds this printer supports. */ - abstract get speedTable(): ReadonlyMap; - /** Gets the max value of the darkness, to map to a percent. */ - abstract get maxDarkness(): number; - - /** Determine if a given speed will work with this model. */ - public isSpeedValid(speed: PrintSpeed): boolean { - return this.speedTable.has(speed); - } - - /** Get the raw value this model understands as the speed. */ - public getSpeedValue(speed: PrintSpeed): number | undefined { - const val = this.speedTable.get(speed) ?? this.speedTable[PrintSpeed.ipsAuto]; - return val; - } - - /** Get a print speed for this printer for */ - public fromRawSpeed(rawSpeed: number): PrintSpeed { - for (const [key, val] of this.speedTable) { - if ( - val === rawSpeed && - key != PrintSpeed.ipsAuto && - key != PrintSpeed.ipsPrinterMax && - key != PrintSpeed.ipsPrinterMin - ) { - return key; - } - } - return PrintSpeed.ipsAuto; + /** Gets the command language for this printer. */ + abstract get commandLanguage(): PrinterCommandLanguage; + /** Gets the DPI of this printer. */ + abstract get dpi(): number; + /** Gets the model of this printer. */ + abstract get model(): PrinterModel | string; + + // Speed is determined by what the printer supports + // EPL printers have a table that determines their setting and it needs to be hardcoded. + // ZPL printers follow this pattern: + // 1 = 25.4 mm/sec. (1 inch/sec.) + // A or 2 = 50.8 mm/sec. (2 inches/sec.) + // A is the default print and backfeed speed + // B or 3 = 76.2 mm/sec. (3 inches/sec.) + // C or 4 = 101.6 mm/sec. (4 inches/sec.) + // 5 = 127 mm/sec. (5 inches/sec.) + // D or 6 = 152.4 mm/sec. (6 inches/sec.) + // D is the default media slew speed + // 7 = 177.8 mm/sec. (7 inches/sec.) + // E or 8 = 203.2 mm/sec. (8 inches/sec.) + // 9 = 220.5 mm/sec. (9 inches/sec.) + // 10 = 245 mm/sec. (10 inches/sec.) + // 11 = 269.5 mm/sec. (11 inches/sec.) + // 12 = 304.8 mm/sec. (12 inches/sec.) + // 13 = 13 in/sec + // 14 = 14 in/sec + // This gets encoded into the speed table. + // Every speed table should also have entries for ipsPrinterMin, ipsPrinterMax, and auto. + // These should be duplicate entries of real values in the speed table so that + // we have sane defaults for commands to default to. + /** Gets the map of speeds this printer supports. */ + abstract get speedTable(): ReadonlyMap; + /** Gets the max value of the darkness, to map to a percent. */ + abstract get maxDarkness(): number; + + /** Determine if a given speed will work with this model. */ + public isSpeedValid(speed: PrintSpeed): boolean { + return this.speedTable.has(speed); + } + + /** Get the raw value this model understands as the speed. */ + public getSpeedValue(speed: PrintSpeed): number { + const val = this.speedTable.get(speed) ?? this.speedTable.get(PrintSpeed.ipsAuto); + return val ?? 0; + } + + /** Get a print speed for this printer for */ + public fromRawSpeed(rawSpeed: number): PrintSpeed { + for (const [key, val] of this.speedTable) { + if ( + val === rawSpeed && + key != PrintSpeed.ipsAuto && + key != PrintSpeed.ipsPrinterMax && + key != PrintSpeed.ipsPrinterMin + ) { + return key; + } } + return PrintSpeed.ipsAuto; + } } /** Class representing a printer that could not be identified. */ export class UnknownPrinter extends BasePrinterInfo { - get commandLanguage(): PrinterCommandLanguage { - return PrinterCommandLanguage.none; - } - get speedTable(): ReadonlyMap { - throw new WebZlpError('Unknown printer, cannot read metadata.'); - } - get model(): PrinterModel { - return PrinterModel.unknown; - } - get dpi(): number { - throw new WebZlpError('Unknown printer, cannot read metadata.'); - } - get maxDarkness(): number { - throw new WebZlpError('Unknown printer, cannot read metadata.'); - } + get commandLanguage(): PrinterCommandLanguage { + return PrinterCommandLanguage.none; + } + get speedTable(): ReadonlyMap { + throw new WebZlpError('Unknown printer, cannot read metadata.'); + } + get model(): PrinterModel { + return PrinterModel.unknown; + } + get dpi(): number { + throw new WebZlpError('Unknown printer, cannot read metadata.'); + } + get maxDarkness(): number { + throw new WebZlpError('Unknown printer, cannot read metadata.'); + } } /** A printer model object that was autodetected from the printer itself. */ export class AutodetectedPrinter extends BasePrinterInfo { - get commandLanguage(): PrinterCommandLanguage { - return this._commandLanugage; - } - get dpi(): number { - return this._dpi; - } - get model(): PrinterModel | string { - return this._model; - } - get speedTable(): ReadonlyMap { - return this._speedTable; - } - get maxDarkness(): number { - return this._maxDarkness; - } - - constructor( - private _commandLanugage: PrinterCommandLanguage, - private _dpi: number, - private _model: PrinterModel | string, - private _speedTable: ReadonlyMap, - private _maxDarkness: number - ) { - super(); - } + get commandLanguage(): PrinterCommandLanguage { + return this._commandLanugage; + } + get dpi(): number { + return this._dpi; + } + get model(): PrinterModel | string { + return this._model; + } + get speedTable(): ReadonlyMap { + return this._speedTable; + } + get maxDarkness(): number { + return this._maxDarkness; + } + + constructor( + private _commandLanugage: PrinterCommandLanguage, + private _dpi: number, + private _model: PrinterModel | string, + private _speedTable: ReadonlyMap, + private _maxDarkness: number + ) { + super(); + } } diff --git a/src/Printers/Models/PrinterModelDb.ts b/src/Printers/Models/PrinterModelDb.ts index 1921c0d..544c512 100644 --- a/src/Printers/Models/PrinterModelDb.ts +++ b/src/Printers/Models/PrinterModelDb.ts @@ -1,100 +1,103 @@ import { PrinterModel } from './PrinterModel.js'; import { PrinterCommandLanguage } from '../Configuration/PrinterOptions.js'; import * as EPL from './EplPrinterModels.js'; -import { IPrinterModelInfo, UnknownPrinter } from './PrinterModel.js'; +import { type IPrinterModelInfo, UnknownPrinter } from './PrinterModel.js'; +import type { IDeviceInformation } from '../Communication/DeviceCommunication.js'; export class PrinterModelDb { - /** Determine a printer model based on the printer-reported model. */ - public static getModel(rawModelId: string): PrinterModel { - if (rawModelId == null) { - return PrinterModel.unknown; - } - // Easy mode: if it ends in FDX it's a fedex LP2844 - if (rawModelId.endsWith('FDX')) { - return PrinterModel.lp2844fedex; - } - if (rawModelId.endsWith('UPS')) { - return PrinterModel.lp2844ups; - } + /** Determine a printer model based on the printer-reported model. */ + public static getModel(rawModelId?: string): PrinterModel { + if (rawModelId === undefined) { + return PrinterModel.unknown; + } + // Easy mode: if it ends in FDX it's a fedex LP2844 + if (rawModelId.endsWith('FDX')) { + return PrinterModel.lp2844fedex; + } + if (rawModelId.endsWith('UPS')) { + return PrinterModel.lp2844ups; + } - // Hard mode: Model correlation between observed values and output. - // This is pretty much all based off of observed values, I can't find a mapping - // of the config's model number vs the hardware model number. - // TODO: Make this extensible so it's possible for consumers to add their own - // printers to the enum, match list, etc. - switch (rawModelId) { - case 'UKQ1915 U': - // TODO: This is an educated guess, validate it! - return PrinterModel.tlp2824; - case 'UKQ1935 U': - return PrinterModel.tlp2844; + // Hard mode: Model correlation between observed values and output. + // This is pretty much all based off of observed values, I can't find a mapping + // of the config's model number vs the hardware model number. + // TODO: Make this extensible so it's possible for consumers to add their own + // printers to the enum, match list, etc. + switch (rawModelId) { + case 'UKQ1915 U': + // TODO: This is an educated guess, validate it! + return PrinterModel.tlp2824; + case 'UKQ1935 U': + return PrinterModel.tlp2844; - case 'UKQ1915HLU': - return PrinterModel.lp2824; - case 'UKQ1935HLU': - return PrinterModel.lp2844; - case 'UKQ1935HMU': - // HMU units that do not have FDX in the version string appear to be UPS - // units. Maybe. Mostly. It's not clear. - return PrinterModel.lp2844ups; + case 'UKQ1915HLU': + return PrinterModel.lp2824; + case 'UKQ1935HLU': + return PrinterModel.lp2844; + case 'UKQ1935HMU': + // HMU units that do not have FDX in the version string appear to be UPS + // units. Maybe. Mostly. It's not clear. + return PrinterModel.lp2844ups; - case 'LP2824-Z-200dpi': - return PrinterModel.lp2824z; - case 'LP2844-Z-200dpi': - return PrinterModel.lp2844z; - default: - return PrinterModel.unknown; - } + case 'ZPL_AUTODETECT': + return PrinterModel.zplAutodetect; + case 'LP2824-Z-200dpi': + return PrinterModel.lp2824z; + case 'LP2844-Z-200dpi': + return PrinterModel.lp2844z; + default: + return PrinterModel.unknown; } + } - /** Look up the model information for a given printer model. */ - public static getModelInfo(model: PrinterModel): IPrinterModelInfo { - // TODO: Make this extensible so it's possible for consumers to add their own - // printers to the enum, match list, etc. - switch (model) { - // LP models, direct thermal only. - case PrinterModel.lp2824: - return new EPL.LP2824(); - case PrinterModel.lp2844: - case PrinterModel.lp2844fedex: - case PrinterModel.lp2844ups: - return new EPL.LP2844(); + /** Look up the model information for a given printer model. */ + public static getModelInfo(model: PrinterModel): IPrinterModelInfo { + // TODO: Make this extensible so it's possible for consumers to add their own + // printers to the enum, match list, etc. + switch (model) { + // LP models, direct thermal only. + case PrinterModel.lp2824: + return new EPL.LP2824(); + case PrinterModel.lp2844: + case PrinterModel.lp2844fedex: + case PrinterModel.lp2844ups: + return new EPL.LP2844(); - // TLP models, direct thermal or thermal transfer. - case PrinterModel.tlp2824: - return new EPL.TLP2824(); - case PrinterModel.tlp2844: - return new EPL.TLP2844(); + // TLP models, direct thermal or thermal transfer. + case PrinterModel.tlp2824: + return new EPL.TLP2824(); + case PrinterModel.tlp2844: + return new EPL.TLP2844(); - default: - return new UnknownPrinter(); - } + default: + return new UnknownPrinter(); } + } - public static guessLanguageFromModelHint(modelHint?: string): PrinterCommandLanguage { - if (!modelHint) { - return PrinterCommandLanguage.none; - } + public static guessLanguageFromModelHint(deviceInfo?: IDeviceInformation): PrinterCommandLanguage { + if (deviceInfo === undefined) { return PrinterCommandLanguage.none; } - // ZPL printers tend to be more trustworthy. They will follow a more standard - // format. - switch (true) { - // LP2844 - // ZTC LP2844-Z-200dpi - case /\sLP2844-Z-200dpi/gim.test(modelHint): - return PrinterCommandLanguage.zplEmulateEpl; - default: - return PrinterCommandLanguage.none; - } + const modelName = deviceInfo.productName ?? ''; + // ZPL printers tend to be more trustworthy. They will follow a more standard + // format. + switch (true) { + // LP2844-Z + // ZTC LP2844-Z-200dpi + case /\sLP2844-Z-200dpi/gim.test(modelName): + case /\sLP2824-Z-200dpi/gim.test(modelName): + return PrinterCommandLanguage.zplEmulateEpl; + default: + return PrinterCommandLanguage.none; + } - // EPL printers are all over the place. They range from blank to straight up lies. - // I have an LP 2844 that claims to be a TPL2844 (it is not). - // I have a FedEx unit that is blank. - // I have a UPS unit that says UPS. I have another one that doesn't. - // EPL printer model hints are not to be trusted. + // EPL printers are all over the place. They range from blank to straight up lies. + // I have an LP 2844 that claims to be a TPL2844 (it is not). + // I have a FedEx unit that is blank. + // I have a UPS unit that says UPS. I have another one that doesn't. + // EPL printer model hints are not to be trusted. - // I don't have a CPCL printer to test and see what it might say. Someday I - // may get my hands on one to test. If you'd like me to try one out contact me! - // I'll be happy to discuss sending one to me to test and implement then send back. - } + // I don't have a CPCL printer to test and see what it might say. Someday I + // may get my hands on one to test. If you'd like me to try one out contact me! + // I'll be happy to discuss sending one to me to test and implement then send back. + } } diff --git a/src/Printers/Printer.ts b/src/Printers/Printer.ts index 87ac7ac..1874e10 100644 --- a/src/Printers/Printer.ts +++ b/src/Printers/Printer.ts @@ -1,262 +1,219 @@ -import { IDocument } from '../Documents/Document.js'; -import { ConfigDocumentBuilder, IConfigDocumentBuilder } from '../Documents/ConfigDocument.js'; +import { type IDocument } from '../Documents/Document.js'; +import { ConfigDocumentBuilder, type IConfigDocumentBuilder } from '../Documents/ConfigDocument.js'; import { - ILabelDocumentBuilder, - LabelDocumentBuilder, - LabelDocumentType + type ILabelDocumentBuilder, + LabelDocumentBuilder, + LabelDocumentType } from '../Documents/LabelDocument.js'; import { ReadyToPrintDocuments } from '../Documents/ReadyToPrintDocuments.js'; import { WebZlpError } from '../WebZlpError.js'; -import { IPrinterDeviceChannel, PrinterChannelType } from './Communication/PrinterCommunication.js'; -import { UsbPrinterDeviceChannel } from './Communication/UsbPrinterDeviceChannel.js'; +import { UsbDeviceChannel } from './Communication/UsbPrinterDeviceChannel.js'; import { PrinterCommandLanguage, PrinterOptions } from './Configuration/PrinterOptions.js'; import { EplPrinterCommandSet } from './Languages/EplPrinterCommandSet.js'; import { PrinterCommandSet } from './Languages/PrinterCommandSet.js'; import { ZplPrinterCommandSet } from './Languages/ZplPrinterCommandSet.js'; import { PrinterModelDb } from './Models/PrinterModelDb.js'; -import { PrinterCommunicationOptions } from './PrinterCommunicationOptions.js'; +import { DeviceNotReadyError, type IDeviceChannel, type IDeviceCommunicationOptions, DeviceCommunicationError, type IDeviceInformation, type IDevice } from './Communication/DeviceCommunication.js'; /** * A class for working with a label printer. */ -export class Printer { - // Printer communication handles - private channelType: PrinterChannelType; - private device: USBDevice; - private printerChannel: IPrinterDeviceChannel; - private commandset: PrinterCommandSet; - - private _printerConfig: PrinterOptions; - - private _ready: Promise; - /** A promise indicating this printer is ready to be used. */ - get ready() { - return this._ready; - } - - /** Gets the model of the printer, detected from the printer's config. */ - get printerModel() { - return this._printerConfig.model; - } - - /** Gets the read-only copy of the current config of the printer. To modfiy use getConfigDocument. */ - get printerConfig() { - return this._printerConfig.copy(); - } - - private _printerCommunicationOptions: PrinterCommunicationOptions; - /** Gets the configured printer communication options. */ - get printerCommunicationOptions() { - return this._printerCommunicationOptions; - } - - /** Construct a new printer from a given USB device. */ - static fromUSBDevice(device: USBDevice, options?: PrinterCommunicationOptions): Printer { - return new this(PrinterChannelType.usb, device, options); - } - - constructor( - channelType: PrinterChannelType, - device: USBDevice, - options?: PrinterCommunicationOptions - ) { - this.channelType = channelType; - this._printerCommunicationOptions = options ?? new PrinterCommunicationOptions(); - - switch (this.channelType) { - case PrinterChannelType.usb: - this.device = device; - this.printerChannel = new UsbPrinterDeviceChannel( - this.device, - this._printerCommunicationOptions.debug - ); - break; - case PrinterChannelType.serial: - case PrinterChannelType.bluetooth: - case PrinterChannelType.network: - throw new WebZlpError('Printer comm method not implemented.'); - } - - this._ready = this.setup(); - } - - private async setup() { - await this.printerChannel.ready; - await this.refreshPrinterConfiguration(this.printerChannel.modelHint); - return true; - } - - /** Gets a document for configuring this printer. */ - public getConfigDocument(): IConfigDocumentBuilder { - return new ConfigDocumentBuilder(this._printerConfig); - } - - /** Gets a document for printing a label. */ - public getLabelDocument( - docType: LabelDocumentType = LabelDocumentType.instanceForm - ): ILabelDocumentBuilder { - return new LabelDocumentBuilder(this._printerConfig, docType); - } - - /** Send a document to the printer, applying the commands. */ - public async sendDocument(doc: IDocument) { - await this.ready; - - if (this._printerCommunicationOptions.debug) { - console.debug('SENDING COMMANDS TO PRINTER:'); - console.debug(doc.showCommands()); - } - - // Exceptions are thrown and handled elsewhere. - const compiled = this.commandset.transpileDoc(doc); - - if (this._printerCommunicationOptions.debug) { - console.debug('RAW COMMAND BUFFER:'); - console.debug(compiled.commandBufferString); - } - - await this.printerChannel.sendCommands(compiled.commandBuffer); - } - - /** Close the connection to this printer, preventing future communication from working. */ - public async dispose() { - await this.printerChannel.dispose(); +export class LabelPrinter implements IDevice { + // Printer communication handles + private _channel: IDeviceChannel; + private _commandSet?: PrinterCommandSet; + + private _printerOptions: PrinterOptions; + /** Gets the read-only copy of the current config of the printer. To modify use getConfigDocument. */ + get printerOptions() { return this._printerOptions.copy(); } + /** Gets the model of the printer, detected from the printer's config. */ + get printerModel() { return this._printerOptions.model; } + /** Gets the serial number of the printer, detected from the printer's config. */ + get printerSerial() { return this._printerOptions.serialNumber; } + + private _deviceCommOpts: IDeviceCommunicationOptions; + /** Gets the configured printer communication options. */ + get printerCommunicationOptions() { + return this._deviceCommOpts; + } + + private _disposed = false; + private _ready: Promise; + /** A promise indicating this printer is ready to be used. */ + get ready() { + return this._ready; + } + get connected() { + return !this._disposed + && this._channel.connected + } + + /** Construct a new printer from a given USB device. */ + static fromUSBDevice( + device: USBDevice, + options: IDeviceCommunicationOptions + ): LabelPrinter { + return new LabelPrinter(new UsbDeviceChannel(device, options), options); + } + + constructor( + channel: IDeviceChannel, + deviceCommunicationOptions: IDeviceCommunicationOptions = { debug: false }, + printerOptions?: PrinterOptions, + ) { + this._channel = channel; + this._deviceCommOpts = deviceCommunicationOptions; + this._printerOptions = printerOptions ?? PrinterOptions.invalid; + this._ready = this.setup(); + } + + private async setup() { + const channelReady = await this._channel.ready; + if (!channelReady) { + // If the channel failed to connect we have no hope. + return false; + } + + await this.refreshPrinterConfiguration(this._channel.getDeviceInfo()); + return true; + } + + /** Gets a document for configuring this printer. */ + public getConfigDocument(): IConfigDocumentBuilder { + return new ConfigDocumentBuilder(this._printerOptions); + } + + /** Gets a document for printing a label. */ + public getLabelDocument( + docType: LabelDocumentType = LabelDocumentType.instanceForm + ): ILabelDocumentBuilder { + return new LabelDocumentBuilder(this._printerOptions, docType); + } + + /** Send a document to the printer, applying the commands. */ + public async sendDocument(doc: IDocument) { + await this.ready; + if (!this.connected || this._commandSet === undefined) { + throw new DeviceNotReadyError("Printer is not ready to communicate."); + } + + if (this._deviceCommOpts.debug) { + console.debug('SENDING COMMANDS TO PRINTER:'); + console.debug(doc.showCommands()); + } + + // Exceptions are thrown and handled elsewhere. + const compiled = this._commandSet.transpileDoc(doc); + + if (this._deviceCommOpts.debug) { + console.debug('RAW COMMAND BUFFER:'); + console.debug(compiled.commandBufferString); + } + + await this._channel.sendCommands(compiled.commandBuffer); + } + + /** Close the connection to this printer, preventing future communication. */ + public async dispose() { + this._disposed = true; + this._ready = Promise.resolve(false); + await this._channel.dispose(); + } + + /** Refresh the printer information cache directly from the printer. */ + public async refreshPrinterConfiguration(deviceInfo?: IDeviceInformation): Promise { + if (!this._printerOptions.valid) { + // First time pulling the config. Detect language and model. + this._printerOptions = await this.detectLanguageAndSetConfig(deviceInfo); + } else { + this._printerOptions = await this.tryGetConfig(this._commandSet); + } + + if (!this._printerOptions.valid) { + throw new WebZlpError( + 'Failed to detect the printer information, either the printer is unknown or the config can not be parsed. This printer can not be used.' + ); + } + return this._printerOptions; + } + + private async detectLanguageAndSetConfig(deviceInfo?: IDeviceInformation): Promise { + const guess = PrinterModelDb.guessLanguageFromModelHint(deviceInfo); + // Guess order is easiest to detect and support.. to least + const guessOrder = [ + guess, + PrinterCommandLanguage.epl, + PrinterCommandLanguage.zpl, + PrinterCommandLanguage.cpcl + ]; + + // For each language, we send the appropriate command to try and get the + // config dump. If we get something legible back break out. + for (let i = 0; i < guessOrder.length; i++) { + const set = this.getCommandSetForLanguage(guessOrder[i]); + if (set === undefined) { + continue; + } + this.logIfDebug('Trying printer language guess', PrinterCommandLanguage[guessOrder[i]]); + const config = await this.tryGetConfig(set); + if (config.valid) { + this._commandSet = set; + return config; + } } - /** Refresh the printer information cache directly from the printer. */ - public async refreshPrinterConfiguration(modelHint?: string): Promise { - if (!this._printerConfig) { - // First time pulling the config. Detect language and model. - this._printerConfig = await this.detectLanguageAndSetConfig(modelHint); - } else { - this._printerConfig = await this.tryGetConfig(this.commandset); - } + return { valid: false } as PrinterOptions; + } - if (!this._printerConfig?.valid) { - throw new WebZlpError( - 'Failed to detect the printer information, either the printer is unknown or the config can not be parsed. This printer can not be used.' - ); - } - return this._printerConfig; + private getCommandSetForLanguage(lang: PrinterCommandLanguage): PrinterCommandSet | undefined { + // In order of preferred communication method + if (PrinterCommandLanguage.zpl === (lang & PrinterCommandLanguage.zpl)) { + return new ZplPrinterCommandSet(); } - - private async detectLanguageAndSetConfig(modelHint?: string): Promise { - const guess = PrinterModelDb.guessLanguageFromModelHint(modelHint); - // Guess order is easiest to detect and support.. to least - const guessOrder = [ - guess, - PrinterCommandLanguage.epl, - PrinterCommandLanguage.zpl, - PrinterCommandLanguage.cpcl - ]; - - // For each language, we send the appropriate command to try and get the - // config dump. If we get something legible back break out. - for (let i = 0; i < guessOrder.length; i++) { - const set = this.getCommandSetForLanguage(guessOrder[i]); - if (set == null) { - continue; - } - this.logIfDebug('Trying printer language guess', PrinterCommandLanguage[guessOrder[i]]); - const config = await this.tryGetConfig(set); - if (config.valid) { - this.commandset = set; - return config; - } - } - - return { valid: false } as PrinterOptions; + if (PrinterCommandLanguage.epl === (lang & PrinterCommandLanguage.epl)) { + return new EplPrinterCommandSet(); } + return undefined; + } - private getCommandSetForLanguage(lang: PrinterCommandLanguage): PrinterCommandSet { - // In order of preferred communication method - if (PrinterCommandLanguage.zpl === (lang & PrinterCommandLanguage.zpl)) { - return new ZplPrinterCommandSet(); - } - if (PrinterCommandLanguage.epl === (lang & PrinterCommandLanguage.epl)) { - return new EplPrinterCommandSet(); - } - return null; - } + private async tryGetConfig(cmdSet?: PrinterCommandSet): Promise { + let config = PrinterOptions.invalid; + if (cmdSet === undefined) { return config; } - private async tryGetConfig(cmdSet: PrinterCommandSet): Promise { - // TODO: Move this elsewhere so we don't create a new one each time. - // Safe to use a raw document with null metadata since the data isn't used here. - const compiled = cmdSet.transpileDoc(ReadyToPrintDocuments.configDocument); - this.logIfDebug('Querying printer config with', compiled.commandBufferString); + const compiled = cmdSet.transpileDoc(ReadyToPrintDocuments.configDocument); + this.logIfDebug('Querying printer config with', compiled.commandBufferString); - let config: PrinterOptions; - // Querying for a config doesn't always.. work? Like, just straight up - // for reasons I can't figure out some printers will refuse to return - // a valid config. Mostly EPL models. - // Give it 3 chances before we give up. - let retryLimit = 3; - do { - retryLimit--; + // Querying for a config doesn't always.. work? Like, just straight up + // for reasons I can't figure out some printers will refuse to return + // a valid config. Mostly EPL models. + // Give it 3 chances before we give up. + let retryLimit = 3; + do { + retryLimit--; - // Start listening for the return from the - const listenEpl = this.listenForData(); + // Start listening for the return from the printer + const awaitInput = this._channel.getInput(); // this.listenForData(); - // Config isn't set up yet, send command directly without the send command. - await this.printerChannel.sendCommands(compiled.commandBuffer); - const rawResult = await listenEpl; - config = cmdSet.parseConfigurationResponse( - rawResult, - this._printerCommunicationOptions - ); - } while (!config.valid && retryLimit > 0); + // Config isn't set up yet, send command directly without the send command. + await this._channel.sendCommands(compiled.commandBuffer); + const rawResult = await awaitInput; + if (rawResult instanceof DeviceCommunicationError) { + continue; + } + config = cmdSet.parseConfigurationResponse( + rawResult.join(), + this._printerOptions + ); + } while (!config.valid && retryLimit > 0); - this.logIfDebug(`Config result is ${config.valid ? 'valid' : 'not valid.'}`); + this.logIfDebug(`Config result is ${config.valid ? 'valid' : 'not valid.'}`); - return config; - } - - /** Wait for the next line of data sent from the printer, or undefined if nothing is received. */ - private async nextLine(timeoutMs: number): Promise { - let reader: ReadableStreamDefaultReader; - const nextLinePromise = (async () => { - reader = this.printerChannel.streamFromPrinter.getReader(); - const { value, done } = await reader.read(); - reader.releaseLock(); - - if (done) { - return; - } - - return value; - })(); - - const timeoutPromise = new Promise((resolve) => { - setTimeout(() => { - reader.releaseLock(); - resolve(); - }, timeoutMs); - }); - - return Promise.race([nextLinePromise, timeoutPromise]); - } - - /** Listen for incoming data until a timeout, assuming the source is done. */ - private async listenForData(timeoutMs = 300) { - let aggregate = ''; - for (;;) { - const line = await this.nextLine(timeoutMs); - if (line === undefined) { - this.logIfDebug( - 'Received', - aggregate.length, - 'long message from printer:\n', - aggregate - ); - return aggregate; - } - aggregate += line + '\n'; - } - } + return config; + } - private logIfDebug(...obj: unknown[]) { - if (this._printerCommunicationOptions.debug) { - console.debug(...obj); - } + private logIfDebug(...obj: unknown[]) { + if (this._deviceCommOpts.debug) { + console.debug(...obj); } + } } diff --git a/src/Printers/PrinterCommunicationOptions.ts b/src/Printers/PrinterCommunicationOptions.ts deleted file mode 100644 index de606ce..0000000 --- a/src/Printers/PrinterCommunicationOptions.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { PrinterCommandLanguage } from './Configuration/PrinterOptions.js'; -import { - CommandFormInclusionMode, - TranspileCommandDelegate -} from './Languages/PrinterCommandSet.js'; - -export class PrinterCommunicationOptions { - /** - * Value to use for rounding read-from-config label sizes. - * - * When reading the config from a printer the label width and height may be - * variable. When you set the label width to 4 inches it's translated into - * dots, and then the printer adds a calculated offset to that. This offset - * is unique per printer (so far as I have observed) and introduces noise. - * This value rounds the returned value to the nearest fraction of an inch. - * - * For example, with a rounding step of 0.25 (the default) if the printer - * returns a width 4.113 it will be rounded to 4.0 - */ - public labelDimensionRoundingStep = 0.25; - - /** - * Whether to display printer communication to the dev console - */ - public debug = false; - - /** - * Custom printer commands added to the base set for a given language. - * - * See the documentation for more details on how to implement this. - */ - public additionalCustomCommands: Array<{ - commandType: symbol; - applicableLanguages: PrinterCommandLanguage; - transpileDelegate: TranspileCommandDelegate; - commandInclusionMode: CommandFormInclusionMode; - }> = null; -} diff --git a/src/Printers/index.ts b/src/Printers/index.ts new file mode 100644 index 0000000..d2a8686 --- /dev/null +++ b/src/Printers/index.ts @@ -0,0 +1,13 @@ +export * from './Communication/DeviceCommunication.js' +export * from './Communication/LineBreakTransformer.js' +export * from './Communication/UsbPrinterDeviceChannel.js' +export * from './Configuration/MediaOptions.js' +export * from './Configuration/PrinterOptions.js' +export * from './Configuration/SerialPortSettings.js' +export * from './Languages/EplPrinterCommandSet.js' +export * from './Languages/PrinterCommandSet.js' +export * from './Languages/ZplPrinterCommandSet.js' +export * from './Models/EplPrinterModels.js' +export * from './Models/PrinterModel.js' +export * from './Models/PrinterModelDb.js' +export * from './Printer.js' diff --git a/src/WebZlpError.ts b/src/WebZlpError.ts index f92fa70..8a96c26 100644 --- a/src/WebZlpError.ts +++ b/src/WebZlpError.ts @@ -1,7 +1,7 @@ /** Exception thrown from the WebZLP library. */ export class WebZlpError extends Error { - constructor(message: string) { - super(message); - this.name = this.constructor.name; - } + constructor(message: string) { + super(message); + this.name = this.constructor.name; + } } diff --git a/src/index.ts b/src/index.ts index 66936e5..1465698 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,5 @@ -export * from './Color.js'; -export * from './Documents/Commands.js'; -export * from './Documents/ConfigDocument.js'; -export * from './Documents/Document.js'; -export * from './Documents/BitmapGRF.js'; -export * from './Documents/LabelDocument.js'; -export * from './Documents/ReadyToPrintDocuments.js'; -export * from './Printers/Communication/LineBreakTransformer.js'; -export * from './Printers/Communication/PrinterCommunication.js'; -export * from './Printers/Communication/UsbPrinterDeviceChannel.js'; -export * from './Printers/Configuration/PrinterOptions.js'; -export * from './Printers/Languages/EplPrinterCommandSet.js'; -export * from './Printers/Languages/PrinterCommandSet.js'; -export * from './Printers/Models/EplPrinterModels.js'; -export * from './Printers/Models/PrinterModel.js'; -export * from './Printers/Models/PrinterModelDb.js'; -export * from './Printers/PrinterCommunicationOptions.js'; -export * from './Printers/Printer.js'; +export * from './Documents/index.js'; +export * from './Printers/index.js'; +export * from './NumericRange.js'; export * from './PrinterUsbManager.js'; export * from './WebZlpError.js'; diff --git a/tsconfig.json b/tsconfig.json index e5058cc..cd935e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,28 @@ { "compilerOptions": { - "module": "es6", - "types": [], - "lib": ["dom", "esnext"], - "outDir": "./dist/", - "sourceMap": true, - "target": "esnext", + "target": "ES2022", + "module": "nodenext", + "moduleResolution": "nodenext", + "lib": [ + "ESNext", + "DOM", + "DOM.Iterable" + ], + "skipLibCheck": false, + "isolatedModules": true, + "noEmit": true, + "strict": true, + "checkJs": true, "declaration": true, - "moduleResolution": "node" - } + "declarationMap": true, + "noUnusedLocals": true, + "useDefineForClassFields": true, + "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "verbatimModuleSyntax": true, + "incremental": true + }, + "include": [ + "src" + ] } diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..05ab012 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,25 @@ +/// +import path from 'path'; +import packageJson from './package.json'; +import { defineConfig } from 'vite'; +import dts from 'vite-plugin-dts'; +import eslint from 'vite-plugin-eslint'; + +export default defineConfig({ + build: { + lib: { + entry: path.resolve(__dirname, 'src/index.ts'), + name: packageJson.name, + }, + minify: false, + }, + plugins: [dts(), eslint({ + failOnError: false + })], + test: { + coverage: { + reporter: ['text', 'json-summary', 'json'], + reportOnFailure: true, + } + } +});