pax_global_header00006660000000000000000000000064150051737010014511gustar00rootroot0000000000000052 comment=1c1465134945630c5b91c847f37b661cb3a617b7 llparse-7.3.0/000077500000000000000000000000001500517370100131625ustar00rootroot00000000000000llparse-7.3.0/.github/000077500000000000000000000000001500517370100145225ustar00rootroot00000000000000llparse-7.3.0/.github/workflows/000077500000000000000000000000001500517370100165575ustar00rootroot00000000000000llparse-7.3.0/.github/workflows/ci.yml000066400000000000000000000033341500517370100177000ustar00rootroot00000000000000name: CI on: [push, pull_request] env: CI: true permissions: contents: read jobs: test: name: Run tests runs-on: ${{ matrix.os }} strategy: matrix: os: - macos-latest - ubuntu-latest - windows-latest steps: - name: Install clang for Windows if: runner.os == 'Windows' run: | iwr -useb get.scoop.sh -outfile 'install.ps1' .\install.ps1 -RunAsAdmin scoop install llvm --global # Scoop modifies the PATH so we make the modified PATH global. echo $env:PATH >> $env:GITHUB_PATH - name: Fetch code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1 - name: Setup Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 'lts/*' cache: 'npm' cache-dependency-path: package-lock.json - name: Install dependencies run: npm ci --ignore-scripts - name: Run tests run: npm run test lint: name: Run Lint runs-on: ubuntu-latest steps: - name: Fetch code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 1 - name: Restore node_modules cache uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Install dependencies run: npm ci --ignore-scripts - name: Run lint command run: npm run lint llparse-7.3.0/.gitignore000066400000000000000000000000531500517370100151500ustar00rootroot00000000000000node_modules/ npm-debug.log lib/ test/tmp/ llparse-7.3.0/.travis.yml000066400000000000000000000001241500517370100152700ustar00rootroot00000000000000sudo: false language: node_js node_js: - "stable" script: CFLAGS="-O0" npm test llparse-7.3.0/CNAME000066400000000000000000000000131500517370100137220ustar00rootroot00000000000000llparse.orgllparse-7.3.0/CODE_OF_CONDUCT.md000066400000000000000000000003171500517370100157620ustar00rootroot00000000000000# Code of Conduct * [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md) * [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/master/Moderation-Policy.md) llparse-7.3.0/LICENSE-MIT000066400000000000000000000021211500517370100146120ustar00rootroot00000000000000This software is licensed under the MIT License. Copyright Fedor Indutny, 2018. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. llparse-7.3.0/README.md000066400000000000000000000052111500517370100144400ustar00rootroot00000000000000# llparse [![Build Status](https://secure.travis-ci.org/nodejs/llparse.svg)](http://travis-ci.org/nodejs/llparse) [![NPM version](https://badge.fury.io/js/llparse.svg)](https://badge.fury.io/js/llparse) An API for compiling an incremental parser into a C output. ## Usage ```ts import { LLParse } from 'llparse'; const p = new LLParse('http_parser'); const method = p.node('method'); const beforeUrl = p.node('before_url'); const urlSpan = p.span(p.code.span('on_url')); const url = p.node('url'); const http = p.node('http'); // Add custom uint8_t property to the state p.property('i8', 'method'); // Store method inside a custom property const onMethod = p.invoke(p.code.store('method'), beforeUrl); // Invoke custom C function const complete = p.invoke(p.code.match('on_complete'), { // Restart 0: method }, p.error(4, '`on_complete` error')); method .select({ 'HEAD': 0, 'GET': 1, 'POST': 2, 'PUT': 3, 'DELETE': 4, 'OPTIONS': 5, 'CONNECT': 6, 'TRACE': 7, 'PATCH': 8 }, onMethod) .otherwise(p.error(5, 'Expected method')); beforeUrl .match(' ', beforeUrl) .otherwise(urlSpan.start(url)); url .peek(' ', urlSpan.end(http)) .skipTo(url); http .match(' HTTP/1.1\r\n\r\n', complete) .otherwise(p.error(6, 'Expected HTTP/1.1 and two newlines')); const artifacts = p.build(method); console.log('----- C -----'); console.log(artifacts.c); // string console.log('----- C END -----'); console.log('----- HEADER -----'); console.log(artifacts.header); console.log('----- HEADER END -----'); ``` #### LICENSE This software is licensed under the MIT License. Copyright Fedor Indutny, 2020. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [3]: https://llvm.org/docs/LangRef.html llparse-7.3.0/_config.yml000066400000000000000000000000341500517370100153060ustar00rootroot00000000000000theme: jekyll-theme-midnightllparse-7.3.0/eslint.json000066400000000000000000000026521500517370100153600ustar00rootroot00000000000000{ "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:@stylistic/recommended-extends" ], "rules": { "max-len": [ "error", { "code": 120 } ], "no-console": "error", "@typescript-eslint/no-unused-vars": "error", "@stylistic/array-bracket-spacing": [ "error", "always" ], "@stylistic/operator-linebreak": [ "error", "after" ], "@stylistic/brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], "@stylistic/member-delimiter-style": [ "error", { "overrides": { "interface": { "multiline": { "delimiter": "semi", "requireLast": true } } } } ], "indent": "off", "@stylistic/indent": [ "error", 2, { "SwitchCase": 1, "FunctionDeclaration": { "parameters": "first" }, "FunctionExpression": { "parameters": "first" } } ], "semi": "off", "@stylistic/semi": [ "error", "always" ] }, "parser": "@typescript-eslint/parser", "parserOptions": { "project": [ "tsconfig.eslint.json" ], "sourceType": "module", "ecmaFeatures": { "jsx": true, "modules": true, "experimentalObjectRestSpread": true } } } llparse-7.3.0/examples/000077500000000000000000000000001500517370100150005ustar00rootroot00000000000000llparse-7.3.0/examples/http/000077500000000000000000000000001500517370100157575ustar00rootroot00000000000000llparse-7.3.0/examples/http/.gitignore000066400000000000000000000000351500517370100177450ustar00rootroot00000000000000http *.c *.ll *.h *.o *.dSYM llparse-7.3.0/examples/http/Makefile000066400000000000000000000002721500517370100174200ustar00rootroot00000000000000CC ?= clang all: http http: main.c http_parser.bc $(CC) -g3 -flto -Os -fvisibility=hidden -Wall -I. http_parser.c main.c -o $@ http_parser.bc: index.ts npx ts-node $< .PHONY = all llparse-7.3.0/examples/http/index.ts000066400000000000000000000024231500517370100174370ustar00rootroot00000000000000import { LLParse } from '../../src/api'; const p = new LLParse('http_parser'); const method = p.node('method'); const beforeUrl = p.node('before_url'); const urlSpan = p.span(p.code.span('on_url')); const url = p.node('url'); const http = p.node('http'); // Add custom uint8_t property to the state p.property('i8', 'method'); // Store method inside a custom property const onMethod = p.invoke(p.code.store('method'), beforeUrl); // Invoke custom C function const complete = p.invoke(p.code.match('on_complete'), { // Restart 0: method }, p.error(4, '`on_complete` error')); method .select({ 'HEAD': 0, 'GET': 1, 'POST': 2, 'PUT': 3, 'DELETE': 4, 'OPTIONS': 5, 'CONNECT': 6, 'TRACE': 7, 'PATCH': 8 }, onMethod) .otherwise(p.error(5, 'Expected method')); beforeUrl .match(' ', beforeUrl) .otherwise(urlSpan.start(url)); url .peek(' ', urlSpan.end(http)) .skipTo(url); http .match(' HTTP/1.1\r\n\r\n', complete) .match(' HTTP/1.1\n\n', complete) .otherwise(p.error(6, 'Expected HTTP/1.1 and two newlines')); // Build const fs = require('fs'); const path = require('path'); const artifacts = p.build(method); fs.writeFileSync(path.join(__dirname, 'http_parser.h'), artifacts.header); fs.writeFileSync(path.join(__dirname, 'http_parser.c'), artifacts.c); llparse-7.3.0/examples/http/main.c000066400000000000000000000016231500517370100170510ustar00rootroot00000000000000#include #include #include #include #include "http_parser.h" int on_url(http_parser_t* s, const char* p, const char* endp) { if (p == endp) return 0; fprintf(stdout, "method=%d url_part=\"%.*s\"\n", s->method, (int) (endp - p), p); return 0; } int on_complete(http_parser_t* s, const char* p, const char* endp) { fprintf(stdout, "on_complete\n"); return 0; } int main(int argc, char** argv) { http_parser_t s; http_parser_init(&s); for (;;) { char buf[16384]; const char* input; const char* endp; int code; input = fgets(buf, sizeof(buf), stdin); if (input == NULL) break; endp = input + strlen(input); code = http_parser_execute(&s, input, endp); if (code != 0) { fprintf(stderr, "code=%d error=%d reason=%s\n", code, s.error, s.reason); return -1; } } return 0; } llparse-7.3.0/package-lock.json000066400000000000000000003014431500517370100164030ustar00rootroot00000000000000{ "name": "llparse", "version": "7.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "llparse", "version": "7.3.0", "license": "MIT", "dependencies": { "debug": "^4.2.0", "llparse-frontend": "^3.0.0" }, "devDependencies": { "@stylistic/eslint-plugin": "^2.6.1", "@types/debug": "^4.1.5", "@types/mocha": "^8.0.3", "@types/node": "^20.11.16", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "eslint": "^8.56.0", "esm": "^3.2.25", "llparse-test-fixture": "^5.0.1", "mocha": "^9.2.2", "ts-node": "^9.0.0", "typescript": "^5.0.3" } }, "node_modules/@eslint-community/eslint-utils": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "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, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint-community/regexpp": { "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { "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, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/@eslint/js": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", "dev": true, "license": "BSD-3-Clause" }, "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, "license": "MIT", "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, "license": "MIT", "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, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { "node": ">= 8" } }, "node_modules/@stylistic/eslint-plugin": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.13.0.tgz", "integrity": "sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/utils": "^8.13.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "estraverse": "^5.3.0", "picomatch": "^4.0.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { "eslint": ">=8.40.0" } }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, "license": "MIT", "dependencies": { "@types/ms": "*" } }, "node_modules/@types/mocha": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true, "license": "MIT" }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "20.17.30", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz", "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.0.tgz", "integrity": "sha512-evaQJZ/J/S4wisevDvC1KFZkPzRetH8kYZbkgcTRyql3mcKsf+ZFDV1BVWUGTCAW5pQHoqn5gK5b8kn7ou9aFQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.31.0", "@typescript-eslint/type-utils": "8.31.0", "@typescript-eslint/utils": "8.31.0", "@typescript-eslint/visitor-keys": "8.31.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.0.tgz", "integrity": "sha512-67kYYShjBR0jNI5vsf/c3WG4u+zDnCTHTPqVMQguffaWWFs7artgwKmfwdifl+r6XyM5LYLas/dInj2T0SgJyw==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/scope-manager": "8.31.0", "@typescript-eslint/types": "8.31.0", "@typescript-eslint/typescript-estree": "8.31.0", "@typescript-eslint/visitor-keys": "8.31.0", "debug": "^4.3.4" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.0.tgz", "integrity": "sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.31.0", "@typescript-eslint/visitor-keys": "8.31.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/type-utils": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.31.0.tgz", "integrity": "sha512-DJ1N1GdjI7IS7uRlzJuEDCgDQix3ZVYVtgeWEyhyn4iaoitpMBX6Ndd488mXSx0xah/cONAkEaYyylDyAeHMHg==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "8.31.0", "@typescript-eslint/utils": "8.31.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.0.tgz", "integrity": "sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.0.tgz", "integrity": "sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.31.0", "@typescript-eslint/visitor-keys": "8.31.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/utils": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.31.0.tgz", "integrity": "sha512-qi6uPLt9cjTFxAb1zGNgTob4x9ur7xC6mHQJ8GwEzGMGE9tYniublmJaowOJ9V2jUzxrltTPfdG2nKlWsq0+Ww==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.31.0", "@typescript-eslint/types": "8.31.0", "@typescript-eslint/typescript-estree": "8.31.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.0.tgz", "integrity": "sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.31.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true, "license": "ISC" }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, "license": "ISC" }, "node_modules/acorn": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/anymatch/node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true, "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/binary-search": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.6.tgz", "integrity": "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==", "license": "CC0-1.0" }, "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, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true, "license": "ISC" }, "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, "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "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, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=6.0.0" } }, "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, "license": "MIT" }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.1", "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@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.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.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "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.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-scope": { "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, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "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, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "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, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" } }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/flat-cache": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "license": "ISC" }, "node_modules/fsevents": { "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, "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.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==", "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, "engines": { "node": ">=10.13.0" } }, "node_modules/glob/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "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, "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" }, "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, "license": "MIT", "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==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "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, "license": "ISC" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "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, "license": "MIT", "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, "license": "MIT", "engines": { "node": ">=8" } }, "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, "license": "MIT", "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, "license": "MIT", "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, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/llparse": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/llparse/-/llparse-7.2.0.tgz", "integrity": "sha512-sKxBvM2PJ84FpSUUuup/mMFuODM2pG8zcVGJSmMuq+2fdBWK4KwbogV1unnbki1jwYognRvwPR7svsX7gFKzAA==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.2.0", "llparse-frontend": "^3.0.0" } }, "node_modules/llparse-builder": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/llparse-builder/-/llparse-builder-1.5.2.tgz", "integrity": "sha512-i862UNC3YUEdlfK/NUCJxlKjtWjgAI9AJXDRgjcfRHfwFt4Sf8eFPTRsc91/2R9MBZ0kyFdfhi8SVhMsZf1gNQ==", "license": "MIT", "dependencies": { "@types/debug": "4.1.5 ", "binary-search": "^1.3.6", "debug": "^4.2.0" } }, "node_modules/llparse-builder/node_modules/@types/debug": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "license": "MIT" }, "node_modules/llparse-frontend": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/llparse-frontend/-/llparse-frontend-3.0.0.tgz", "integrity": "sha512-G/o0Po2C+G5OtP8MJeQDjDf5qwDxcO7K6x4r6jqGsJwxk7yblbJnRqpmye7G/lZ8dD0Hv5neY4/KB5BhDmEc9Q==", "license": "MIT", "dependencies": { "debug": "^3.2.6", "llparse-builder": "^1.5.2" } }, "node_modules/llparse-frontend/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/llparse-test-fixture": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/llparse-test-fixture/-/llparse-test-fixture-5.1.0.tgz", "integrity": "sha512-HeRay3HmzUPgVXClUGTsXPWhLSibcgW8VQVjPVuT4q6oRXIdjjh886vgXZ69bIQ3XHfy4bE3BhP/tm44oFE8kQ==", "dev": true, "license": "MIT", "dependencies": { "llparse": "^7.0.0", "yargs": "^15.4.1" } }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "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, "license": "ISC" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/micromatch/node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", "dev": true, "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", "debug": "4.3.3", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "4.2.1", "ms": "2.1.3", "nanoid": "3.3.1", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", "which": "2.0.2", "workerpool": "6.2.0", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha" }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "license": "MIT", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/mocha/node_modules/debug/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "license": "MIT" }, "node_modules/mocha/node_modules/minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": ">=10" } }, "node_modules/mocha/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==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/mocha/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==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/mocha/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, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/mocha/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, "engines": { "node": ">=10" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true, "license": "MIT", "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", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "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, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { "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.5" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "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, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/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, "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/readdirp/node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "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, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true, "license": "ISC" }, "node_modules/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, "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/semver": { "version": "7.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true, "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "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==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "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==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "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, "license": "MIT", "engines": { "node": ">=8" }, "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==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "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, "license": "MIT" }, "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, "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { "node": ">=18.12" }, "peerDependencies": { "typescript": ">=4.8.4" } }, "node_modules/ts-node": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "dev": true, "license": "MIT", "dependencies": { "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "source-map-support": "^0.5.17", "yn": "3.1.1" }, "bin": { "ts-node": "dist/bin.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" }, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "typescript": ">=2.7" } }, "node_modules/ts-node/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, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "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, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, "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, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, "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, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true, "license": "ISC" }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true, "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "license": "ISC" }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true, "license": "ISC" }, "node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" }, "engines": { "node": ">=8" } }, "node_modules/yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, "engines": { "node": ">=10" } }, "node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yargs/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, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/yargs/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, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, "node_modules/yargs/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==", "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs/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==", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" }, "engines": { "node": ">=6" } }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/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, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } } } llparse-7.3.0/package.json000066400000000000000000000026541500517370100154570ustar00rootroot00000000000000{ "name": "llparse", "version": "7.3.0", "description": "Compile incremental parsers to C code", "main": "lib/api.js", "types": "lib/api.d.ts", "files": [ "lib", "src" ], "scripts": { "build": "tsc", "clean": "rm -rf lib", "prepare": "npm run clean && npm run build", "lint": "eslint -c eslint.json src/**/*.ts test/**/*.ts", "lint:fix": "eslint --fix -c eslint.json src/**/*.ts test/**/*.ts", "mocha": "mocha --timeout=10000 -r ts-node/register/type-check --reporter spec test/*-test.ts", "test": "npm run mocha && npm run lint" }, "repository": { "type": "git", "url": "git+ssh://git@github.com/nodejs/llparse.git" }, "keywords": [ "llparse", "compiler" ], "author": "Fedor Indutny (http://darksi.de/)", "license": "MIT", "bugs": { "url": "https://github.com/nodejs/llparse/issues" }, "homepage": "https://github.com/nodejs/llparse#readme", "devDependencies": { "@stylistic/eslint-plugin": "^2.6.1", "@types/debug": "^4.1.5", "@types/mocha": "^8.0.3", "@types/node": "^20.11.16", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "eslint": "^8.56.0", "esm": "^3.2.25", "llparse-test-fixture": "^5.0.1", "mocha": "^9.2.2", "ts-node": "^9.0.0", "typescript": "^5.0.3" }, "dependencies": { "debug": "^4.2.0", "llparse-frontend": "^3.0.0" } } llparse-7.3.0/src/000077500000000000000000000000001500517370100137515ustar00rootroot00000000000000llparse-7.3.0/src/api.ts000066400000000000000000000022601500517370100150720ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import source = frontend.source; import { Compiler, ICompilerOptions, ICompilerResult } from './compiler'; export { source, ICompilerOptions, ICompilerResult }; // TODO(indutny): API for disabling/short-circuiting spans /** * LLParse graph builder and compiler. */ export class LLParse extends source.Builder { /** * The prefix controls the names of methods and state struct in generated * public C headers: * * ```c * // state struct * struct PREFIX_t { * ... * } * * int PREFIX_init(PREFIX_t* state); * int PREFIX_execute(PREFIX_t* state, const char* p, const char* endp); * ``` * * @param prefix Prefix to be used when generating public API. */ constructor(private readonly prefix: string = 'llparse') { super(); } /** * Compile LLParse graph to the C code and C headers * * @param root Root node of the parse graph (see `.node()`) * @param options Compiler options. */ public build(root: source.node.Node, options: ICompilerOptions = {}) : ICompilerResult { const c = new Compiler(this.prefix, options); return c.compile(root, this.properties); } } llparse-7.3.0/src/compiler/000077500000000000000000000000001500517370100155635ustar00rootroot00000000000000llparse-7.3.0/src/compiler/header-builder.ts000066400000000000000000000043511500517370100210120ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import source = frontend.source; export interface IHeaderBuilderOptions { readonly prefix: string; readonly headerGuard?: string; readonly properties: ReadonlyArray; readonly spans: ReadonlyArray; } export class HeaderBuilder { public build(options: IHeaderBuilderOptions): string { let res = ''; const PREFIX = options.prefix.toUpperCase().replace(/[^a-z]/gi, '_'); const DEFINE = options.headerGuard === undefined ? `INCLUDE_${PREFIX}_H_` : options.headerGuard; res += `#ifndef ${DEFINE}\n`; res += `#define ${DEFINE}\n`; res += '#ifdef __cplusplus\n'; res += 'extern "C" {\n'; res += '#endif\n'; res += '\n'; res += '#include \n'; res += '\n'; // Structure res += `typedef struct ${options.prefix}_s ${options.prefix}_t;\n`; res += `struct ${options.prefix}_s {\n`; res += ' int32_t _index;\n'; for (const [ index, field ] of options.spans.entries()) { res += ` void* _span_pos${index};\n`; if (field.callbacks.length > 1) { res += ` void* _span_cb${index};\n`; } } res += ' int32_t error;\n'; res += ' const char* reason;\n'; res += ' const char* error_pos;\n'; res += ' void* data;\n'; res += ' void* _current;\n'; for (const prop of options.properties) { let ty: string; if (prop.ty === 'i8') { ty = 'uint8_t'; } else if (prop.ty === 'i16') { ty = 'uint16_t'; } else if (prop.ty === 'i32') { ty = 'uint32_t'; } else if (prop.ty === 'i64') { ty = 'uint64_t'; } else if (prop.ty === 'ptr') { ty = 'void*'; } else { throw new Error( `Unknown state property type: "${prop.ty}"`); } res += ` ${ty} ${prop.name};\n`; } res += '};\n'; res += '\n'; res += `int ${options.prefix}_init(${options.prefix}_t* s);\n`; res += `int ${options.prefix}_execute(${options.prefix}_t* s, ` + 'const char* p, const char* endp);\n'; res += '\n'; res += '#ifdef __cplusplus\n'; res += '} /* extern "C" */\n'; res += '#endif\n'; res += `#endif /* ${DEFINE} */\n`; return res; } } llparse-7.3.0/src/compiler/index.ts000066400000000000000000000037731500517370100172540ustar00rootroot00000000000000import * as debugAPI from 'debug'; import * as frontend from 'llparse-frontend'; import source = frontend.source; import * as cImpl from '../implementation/c'; import { HeaderBuilder } from './header-builder'; const debug = debugAPI('llparse:compiler'); export interface ICompilerOptions { /** * Debug method name * * The method must have following signature: * * ```c * void debug(llparse_t* state, const char* p, const char* endp, * const char* msg); * ``` * * Where `llparse_t` is a parser state type. */ readonly debug?: string; /** * What guard define to use in `#ifndef` in C headers. * * Default value: `prefix` argument */ readonly headerGuard?: string; /** Optional frontend configuration */ readonly frontend?: frontend.IFrontendLazyOptions; /** Optional C-backend configuration */ readonly c?: cImpl.ICPublicOptions; } export interface ICompilerResult { /** * Textual C code */ readonly c: string; /** * Textual C header file */ readonly header: string; } export class Compiler { constructor(public readonly prefix: string, public readonly options: ICompilerOptions) { } public compile(root: source.node.Node, properties: ReadonlyArray): ICompilerResult { debug('Combining implementations'); const container = new frontend.Container(); const c = new cImpl.CCompiler(container, Object.assign({ debug: this.options.debug, }, this.options.c)); debug('Running frontend pass'); const f = new frontend.Frontend(this.prefix, container.build(), this.options.frontend); const info = f.compile(root, properties); debug('Building header'); const hb = new HeaderBuilder(); const header = hb.build({ headerGuard: this.options.headerGuard, prefix: this.prefix, properties, spans: info.spans, }); debug('Building C'); return { header, c: c.compile(info), }; } } llparse-7.3.0/src/implementation/000077500000000000000000000000001500517370100167765ustar00rootroot00000000000000llparse-7.3.0/src/implementation/c/000077500000000000000000000000001500517370100172205ustar00rootroot00000000000000llparse-7.3.0/src/implementation/c/code/000077500000000000000000000000001500517370100201325ustar00rootroot00000000000000llparse-7.3.0/src/implementation/c/code/and.ts000066400000000000000000000005131500517370100212430ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class And extends Field { protected doBuild(ctx: Compilation, out: string[]): void { out.push(`${this.field(ctx)} &= ${this.ref.value};`); out.push('return 0;'); } } llparse-7.3.0/src/implementation/c/code/base.ts000066400000000000000000000004651500517370100214210ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; export abstract class Code { protected cachedDecl: string | undefined; constructor(public readonly ref: T) { } public abstract build(ctx: Compilation, out: string[]): void; } llparse-7.3.0/src/implementation/c/code/external.ts000066400000000000000000000010761500517370100223300ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Code } from './base'; export abstract class External extends Code { public build(ctx: Compilation, out: string[]): void { out.push(`int ${this.ref.name}(`); out.push(` ${ctx.prefix}_t* s, const unsigned char* p,`); if (this.ref.signature === 'value') { out.push(' const unsigned char* endp,'); out.push(' int value);'); } else { out.push(' const unsigned char* endp);'); } } } llparse-7.3.0/src/implementation/c/code/field.ts000066400000000000000000000016531500517370100215720ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Code } from './base'; export abstract class Field extends Code { public build(ctx: Compilation, out: string[]): void { out.push(`int ${this.ref.name}(`); out.push(` ${ctx.prefix}_t* ${ctx.stateArg()},`); out.push(` const unsigned char* ${ctx.posArg()},`); if (this.ref.signature === 'value') { out.push(` const unsigned char* ${ctx.endPosArg()},`); out.push(` int ${ctx.matchVar()}) {`); } else { out.push(` const unsigned char* ${ctx.endPosArg()}) {`); } const tmp: string[] = []; this.doBuild(ctx, tmp); ctx.indent(out, tmp, ' '); out.push('}'); } protected abstract doBuild(ctx: Compilation, out: string[]): void; protected field(ctx: Compilation): string { return `${ctx.stateArg()}->${this.ref.field}`; } } llparse-7.3.0/src/implementation/c/code/index.ts000066400000000000000000000012101500517370100216030ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { And } from './and'; import { External } from './external'; import { IsEqual } from './is-equal'; import { Load } from './load'; import { MulAdd } from './mul-add'; import { Or } from './or'; import { Store } from './store'; import { Test } from './test'; import { Update } from './update'; export * from './base'; class Match extends External {} class Span extends External {} class Value extends External {} export default { And, IsEqual, Load, Match, MulAdd, Or, Span, Store, Test, Update, Value, }; llparse-7.3.0/src/implementation/c/code/is-equal.ts000066400000000000000000000004771500517370100222320ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class IsEqual extends Field { protected doBuild(ctx: Compilation, out: string[]): void { out.push(`return ${this.field(ctx)} == ${this.ref.value};`); } } llparse-7.3.0/src/implementation/c/code/load.ts000066400000000000000000000004441500517370100214230ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class Load extends Field { protected doBuild(ctx: Compilation, out: string[]): void { out.push(`return ${this.field(ctx)};`); } } llparse-7.3.0/src/implementation/c/code/mul-add.ts000066400000000000000000000037171500517370100220350ustar00rootroot00000000000000import * as assert from 'assert'; import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { SIGNED_LIMITS, UNSIGNED_LIMITS, SIGNED_TYPES } from '../constants'; import { Field } from './field'; export class MulAdd extends Field { protected doBuild(ctx: Compilation, out: string[]): void { const options = this.ref.options; const ty = ctx.getFieldType(this.ref.field); let field = this.field(ctx); if (options.signed) { assert(SIGNED_TYPES.has(ty), `Unexpected mulAdd type "${ty}"`); const targetTy = SIGNED_TYPES.get(ty)!; out.push(`${targetTy}* field = (${targetTy}*) &${field};`); field = '(*field)'; } const match = ctx.matchVar(); const limits = options.signed ? SIGNED_LIMITS : UNSIGNED_LIMITS; assert(limits.has(ty), `Unexpected mulAdd type "${ty}"`); const [ min, max ] = limits.get(ty)!; const mulMax = `${max} / ${options.base}`; const mulMin = `${min} / ${options.base}`; out.push('/* Multiplication overflow */'); out.push(`if (${field} > ${mulMax}) {`); out.push(' return 1;'); out.push('}'); if (options.signed) { out.push(`if (${field} < ${mulMin}) {`); out.push(' return 1;'); out.push('}'); } out.push(''); out.push(`${field} *= ${options.base};`); out.push(''); out.push('/* Addition overflow */'); out.push(`if (${match} >= 0) {`); out.push(` if (${field} > ${max} - ${match}) {`); out.push(' return 1;'); out.push(' }'); out.push('} else {'); out.push(` if (${field} < ${min} - ${match}) {`); out.push(' return 1;'); out.push(' }'); out.push('}'); out.push(`${field} += ${match};`); if (options.max !== undefined) { out.push(''); out.push('/* Enforce maximum */'); out.push(`if (${field} > ${options.max}) {`); out.push(' return 1;'); out.push('}'); } out.push('return 0;'); } } llparse-7.3.0/src/implementation/c/code/or.ts000066400000000000000000000005111500517370100211170ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class Or extends Field { protected doBuild(ctx: Compilation, out: string[]): void { out.push(`${this.field(ctx)} |= ${this.ref.value};`); out.push('return 0;'); } } llparse-7.3.0/src/implementation/c/code/store.ts000066400000000000000000000005161500517370100216400ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class Store extends Field { protected doBuild(ctx: Compilation, out: string[]): void { out.push(`${this.field(ctx)} = ${ctx.matchVar()};`); out.push('return 0;'); } } llparse-7.3.0/src/implementation/c/code/test.ts000066400000000000000000000005371500517370100214660ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class Test extends Field { protected doBuild(ctx: Compilation, out: string[]): void { const value = this.ref.value; out.push(`return (${this.field(ctx)} & ${value}) == ${value};`); } } llparse-7.3.0/src/implementation/c/code/update.ts000066400000000000000000000005201500517370100217610ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Field } from './field'; export class Update extends Field { protected doBuild(ctx: Compilation, out: string[]): void { out.push(`${this.field(ctx)} = ${this.ref.value};`); out.push('return 0;'); } } llparse-7.3.0/src/implementation/c/compilation.ts000066400000000000000000000207431500517370100221140ustar00rootroot00000000000000import * as assert from 'assert'; import * as frontend from 'llparse-frontend'; import { CONTAINER_KEY, STATE_ERROR, ARG_STATE, ARG_POS, ARG_ENDPOS, VAR_MATCH, STATE_PREFIX, LABEL_PREFIX, BLOB_PREFIX, } from './constants'; import { Code } from './code'; import { Node } from './node'; import { Transform } from './transform'; import { MatchSequence } from './helpers/match-sequence'; // Number of hex words per line of blob declaration const BLOB_GROUP_SIZE = 11; type WrappedNode = frontend.IWrap; interface IBlob { readonly alignment: number | undefined; readonly buffer: Buffer; readonly name: string; } // TODO(indutny): deduplicate export interface ICompilationOptions { readonly debug?: string; } // TODO(indutny): deduplicate export interface ICompilationProperty { readonly name: string; readonly ty: string; } export class Compilation { private readonly stateMap: Map> = new Map(); private readonly blobs: Map = new Map(); private readonly codeMap: Map> = new Map(); private readonly matchSequence: Map = new Map(); private readonly resumptionTargets: Set = new Set(); constructor(public readonly prefix: string, private readonly properties: ReadonlyArray, resumptionTargets: ReadonlySet, private readonly options: ICompilationOptions) { for (const node of resumptionTargets) { this.resumptionTargets.add(STATE_PREFIX + node.ref.id.name); } } private buildStateEnum(out: string[]): void { out.push('enum llparse_state_e {'); out.push(` ${STATE_ERROR},`); for (const stateName of this.stateMap.keys()) { if (this.resumptionTargets.has(stateName)) { out.push(` ${stateName},`); } } out.push('};'); out.push('typedef enum llparse_state_e llparse_state_t;'); } private buildBlobs(out: string[]): void { if (this.blobs.size === 0) { return; } for (const blob of this.blobs.values()) { const buffer = blob.buffer; let align = ''; if (blob.alignment) { align = ` ALIGN(${blob.alignment})`; } if (blob.alignment) { out.push('#ifdef __SSE4_2__'); } out.push(`static const unsigned char${align} ${blob.name}[] = {`); for (let i = 0; i < buffer.length; i += BLOB_GROUP_SIZE) { const limit = Math.min(buffer.length, i + BLOB_GROUP_SIZE); const hex: string[] = []; for (let j = i; j < limit; j++) { const value = buffer[j]; assert(value !== undefined); hex.push(this.toChar(value)); } let line = ' ' + hex.join(', '); if (limit !== buffer.length) { line += ','; } out.push(line); } out.push(`};`); if (blob.alignment) { out.push('#endif /* __SSE4_2__ */'); } } out.push(''); } private buildMatchSequence(out: string[]): void { if (this.matchSequence.size === 0) { return; } MatchSequence.buildGlobals(out); out.push(''); for (const match of this.matchSequence.values()) { match.build(this, out); out.push(''); } } public reserveSpans(spans: ReadonlyArray): void { for (const span of spans) { for (const callback of span.callbacks) { this.buildCode(this.unwrapCode(callback)); } } } public debug(out: string[], message: string): void { if (this.options.debug === undefined) { return; } const args = [ this.stateArg(), `(const char*) ${this.posArg()}`, `(const char*) ${this.endPosArg()}`, ]; out.push(`${this.options.debug}(${args.join(', ')},`); out.push(` ${this.cstring(message)});`); } public buildGlobals(out: string[]): void { if (this.options.debug !== undefined) { out.push(`void ${this.options.debug}(`); out.push(` ${this.prefix}_t* s, const char* p, const char* endp,`); out.push(' const char* msg);'); } this.buildBlobs(out); this.buildMatchSequence(out); this.buildStateEnum(out); for (const code of this.codeMap.values()) { out.push(''); code.build(this, out); } } public buildResumptionStates(out: string[]): void { this.stateMap.forEach((lines, name) => { if (!this.resumptionTargets.has(name)) { return; } out.push(`case ${name}:`); out.push(`${LABEL_PREFIX}${name}: {`); lines.forEach((line) => out.push(` ${line}`)); out.push(' UNREACHABLE;'); out.push('}'); }); } public buildInternalStates(out: string[]): void { this.stateMap.forEach((lines, name) => { if (this.resumptionTargets.has(name)) { return; } out.push(`${LABEL_PREFIX}${name}: {`); lines.forEach((line) => out.push(` ${line}`)); out.push(' UNREACHABLE;'); out.push('}'); }); } public addState(state: string, lines: ReadonlyArray): void { assert(!this.stateMap.has(state)); this.stateMap.set(state, lines); } public buildCode(code: Code): string { if (this.codeMap.has(code.ref.name)) { assert.strictEqual(this.codeMap.get(code.ref.name)!, code, `Code name conflict for "${code.ref.name}"`); } else { this.codeMap.set(code.ref.name, code); } return code.ref.name; } public getFieldType(field: string): string { for (const property of this.properties) { if (property.name === field) { return property.ty; } } throw new Error(`Field "${field}" not found`); } // Helpers public unwrapCode(code: frontend.IWrap) : Code { const container = code as frontend.ContainerWrap; return container.get(CONTAINER_KEY); } public unwrapNode(node: WrappedNode): Node { const container = node as frontend.ContainerWrap; return container.get(CONTAINER_KEY); } public unwrapTransform(node: frontend.IWrap) : Transform { const container = node as frontend.ContainerWrap; return container.get(CONTAINER_KEY); } public indent(out: string[], lines: ReadonlyArray, pad: string) { for (const line of lines) { out.push(`${pad}${line}`); } } // MatchSequence cache public getMatchSequence( transform: frontend.IWrap, select: Buffer) : string { const wrap = this.unwrapTransform(transform); let res: MatchSequence; if (this.matchSequence.has(wrap.ref.name)) { res = this.matchSequence.get(wrap.ref.name)!; } else { res = new MatchSequence(wrap); this.matchSequence.set(wrap.ref.name, res); } return res.getName(); } // Arguments public stateArg(): string { return ARG_STATE; } public posArg(): string { return ARG_POS; } public endPosArg(): string { return ARG_ENDPOS; } public matchVar(): string { return VAR_MATCH; } // State fields public indexField(): string { return this.stateField('_index'); } public currentField(): string { return this.stateField('_current'); } public errorField(): string { return this.stateField('error'); } public reasonField(): string { return this.stateField('reason'); } public errorPosField(): string { return this.stateField('error_pos'); } public spanPosField(index: number): string { return this.stateField(`_span_pos${index}`); } public spanCbField(index: number): string { return this.stateField(`_span_cb${index}`); } public stateField(name: string): string { return `${this.stateArg()}->${name}`; } // Globals public cstring(value: string): string { return JSON.stringify(value); } public blob(value: Buffer, alignment?: number): string { if (this.blobs.has(value)) { return this.blobs.get(value)!.name; } const res = BLOB_PREFIX + this.blobs.size; this.blobs.set(value, { alignment, buffer: value, name: res, }); return res; } public toChar(value: number): string { const ch = String.fromCharCode(value); // `'`, `\` if (value === 0x27 || value === 0x5c) { return `'\\${ch}'`; } else if (value >= 0x20 && value <= 0x7e) { return `'${ch}'`; } else { return `0x${value.toString(16)}`; } } } llparse-7.3.0/src/implementation/c/constants.ts000066400000000000000000000027471500517370100216160ustar00rootroot00000000000000export const CONTAINER_KEY = 'c'; export const LABEL_PREFIX = ''; export const STATE_PREFIX = 's_n_'; export const STATE_ERROR = 's_error'; export const BLOB_PREFIX = 'llparse_blob'; export const ARG_STATE = 'state'; export const ARG_POS = 'p'; export const ARG_ENDPOS = 'endp'; export const VAR_MATCH = 'match'; // MatchSequence export const SEQUENCE_COMPLETE = 'kMatchComplete'; export const SEQUENCE_MISMATCH = 'kMatchMismatch'; export const SEQUENCE_PAUSE = 'kMatchPause'; export const SIGNED_LIMITS: Map = new Map(); SIGNED_LIMITS.set('i8', [ '-0x80', '0x7f' ]); SIGNED_LIMITS.set('i16', [ '-0x8000', '0x7fff' ]); SIGNED_LIMITS.set('i32', [ '(-0x7fffffff - 1)', '0x7fffffff' ]); SIGNED_LIMITS.set('i64', [ '(-0x7fffffffffffffffLL - 1)', '0x7fffffffffffffffLL' ]); export const UNSIGNED_LIMITS: Map = new Map(); UNSIGNED_LIMITS.set('i8', [ '0', '0xff' ]); UNSIGNED_LIMITS.set('i16', [ '0', '0xffff' ]); UNSIGNED_LIMITS.set('i32', [ '0', '0xffffffff' ]); UNSIGNED_LIMITS.set('i64', [ '0ULL', '0xffffffffffffffffULL' ]); export const UNSIGNED_TYPES: Map = new Map(); UNSIGNED_TYPES.set('i8', 'uint8_t'); UNSIGNED_TYPES.set('i16', 'uint16_t'); UNSIGNED_TYPES.set('i32', 'uint32_t'); UNSIGNED_TYPES.set('i64', 'uint64_t'); export const SIGNED_TYPES: Map = new Map(); SIGNED_TYPES.set('i8', 'int8_t'); SIGNED_TYPES.set('i16', 'int16_t'); SIGNED_TYPES.set('i32', 'int32_t'); SIGNED_TYPES.set('i64', 'int64_t'); llparse-7.3.0/src/implementation/c/helpers/000077500000000000000000000000001500517370100206625ustar00rootroot00000000000000llparse-7.3.0/src/implementation/c/helpers/match-sequence.ts000066400000000000000000000044741500517370100241450ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { SEQUENCE_COMPLETE, SEQUENCE_MISMATCH, SEQUENCE_PAUSE, } from '../constants'; import { Transform } from '../transform'; import { Compilation } from '../compilation'; type TransformWrap = Transform; export class MatchSequence { constructor(private readonly transform: TransformWrap) { } public static buildGlobals(out: string[]): void { out.push('enum llparse_match_status_e {'); out.push(` ${SEQUENCE_COMPLETE},`); out.push(` ${SEQUENCE_PAUSE},`); out.push(` ${SEQUENCE_MISMATCH}`); out.push('};'); out.push('typedef enum llparse_match_status_e llparse_match_status_t;'); out.push(''); out.push('struct llparse_match_s {'); out.push(' llparse_match_status_t status;'); out.push(' const unsigned char* current;'); out.push('};'); out.push('typedef struct llparse_match_s llparse_match_t;'); } public getName(): string { return `llparse__match_sequence_${this.transform.ref.name}`; } public build(ctx: Compilation, out: string[]): void { out.push(`static llparse_match_t ${this.getName()}(`); out.push(` ${ctx.prefix}_t* s, const unsigned char* p,`); out.push(' const unsigned char* endp,'); out.push(' const unsigned char* seq, uint32_t seq_len) {'); // Vars out.push(' uint32_t index;'); out.push(' llparse_match_t res;'); out.push(''); // Body out.push(' index = s->_index;'); out.push(' for (; p != endp; p++) {'); out.push(' unsigned char current;'); out.push(''); out.push(` current = ${this.transform.build(ctx, '*p')};`); out.push(' if (current == seq[index]) {'); out.push(' if (++index == seq_len) {'); out.push(` res.status = ${SEQUENCE_COMPLETE};`); out.push(' goto reset;'); out.push(' }'); out.push(' } else {'); out.push(` res.status = ${SEQUENCE_MISMATCH};`); out.push(' goto reset;'); out.push(' }'); out.push(' }'); out.push(' s->_index = index;'); out.push(` res.status = ${SEQUENCE_PAUSE};`); out.push(' res.current = p;'); out.push(' return res;'); out.push('reset:'); out.push(' s->_index = 0;'); out.push(' res.current = p;'); out.push(' return res;'); out.push('}'); } } llparse-7.3.0/src/implementation/c/index.ts000066400000000000000000000146361500517370100207110ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { ARG_STATE, ARG_POS, ARG_ENDPOS, STATE_ERROR, VAR_MATCH, CONTAINER_KEY, } from './constants'; import { Compilation } from './compilation'; import code from './code'; import node, { Node } from './node'; import transform from './transform'; export interface ICCompilerOptions { readonly debug?: string; readonly header?: string; } export interface ICPublicOptions { readonly header?: string; } export class CCompiler { constructor(container: frontend.Container, public readonly options: ICCompilerOptions) { container.add(CONTAINER_KEY, { code, node, transform }); } public compile(info: frontend.IFrontendResult): string { const compilation = new Compilation(info.prefix, info.properties, info.resumptionTargets, this.options); const out: string[] = []; out.push('#include '); out.push('#include '); out.push('#include '); out.push(''); // NOTE: Inspired by https://github.com/h2o/picohttpparser // TODO(indutny): Windows support for SSE4.2. // See: https://github.com/nodejs/llparse/pull/24#discussion_r299789676 // (There is no `__SSE4_2__` define for MSVC) out.push('#ifdef __SSE4_2__'); out.push(' #ifdef _MSC_VER'); out.push(' #include '); out.push(' #else /* !_MSC_VER */'); out.push(' #include '); out.push(' #endif /* _MSC_VER */'); out.push('#endif /* __SSE4_2__ */'); out.push(''); out.push('#ifdef __ARM_NEON__'); out.push(' #include '); out.push('#endif /* __ARM_NEON__ */'); out.push(''); out.push('#ifdef __wasm__'); out.push(' #include '); out.push('#endif /* __wasm__ */'); out.push(''); out.push('#ifdef _MSC_VER'); out.push(' #define ALIGN(n) _declspec(align(n))'); out.push(' #define UNREACHABLE __assume(0)'); out.push('#else /* !_MSC_VER */'); out.push(' #define ALIGN(n) __attribute__((aligned(n)))'); out.push(' #define UNREACHABLE __builtin_unreachable()'); out.push('#endif /* _MSC_VER */'); out.push(''); out.push(`#include "${this.options.header || info.prefix}.h"`); out.push(``); out.push(`typedef int (*${info.prefix}__span_cb)(`); out.push(` ${info.prefix}_t*, const char*, const char*);`); out.push(''); // Queue span callbacks to be built before `executeSpans()` code gets called // below. compilation.reserveSpans(info.spans); const root = info.root as frontend.ContainerWrap; const rootState = root.get>(CONTAINER_KEY) .build(compilation); compilation.buildGlobals(out); out.push(''); out.push(`int ${info.prefix}_init(${info.prefix}_t* ${ARG_STATE}) {`); out.push(` memset(${ARG_STATE}, 0, sizeof(*${ARG_STATE}));`); out.push(` ${ARG_STATE}->_current = (void*) (intptr_t) ${rootState};`); out.push(' return 0;'); out.push('}'); out.push(''); out.push(`static llparse_state_t ${info.prefix}__run(`); out.push(` ${info.prefix}_t* ${ARG_STATE},`); out.push(` const unsigned char* ${ARG_POS},`); out.push(` const unsigned char* ${ARG_ENDPOS}) {`); out.push(` int ${VAR_MATCH};`); out.push(` switch ((llparse_state_t) (intptr_t) ` + `${compilation.currentField()}) {`); let tmp: string[] = []; compilation.buildResumptionStates(tmp); compilation.indent(out, tmp, ' '); out.push(' default:'); out.push(' UNREACHABLE;'); out.push(' }'); tmp = []; compilation.buildInternalStates(tmp); compilation.indent(out, tmp, ' '); out.push('}'); out.push(''); out.push(`int ${info.prefix}_execute(${info.prefix}_t* ${ARG_STATE}, ` + `const char* ${ARG_POS}, const char* ${ARG_ENDPOS}) {`); out.push(' llparse_state_t next;'); out.push(''); out.push(' /* check lingering errors */'); out.push(` if (${compilation.errorField()} != 0) {`); out.push(` return ${compilation.errorField()};`); out.push(' }'); out.push(''); tmp = []; this.restartSpans(compilation, info, tmp); compilation.indent(out, tmp, ' '); const args = [ compilation.stateArg(), `(const unsigned char*) ${compilation.posArg()}`, `(const unsigned char*) ${compilation.endPosArg()}`, ]; out.push(` next = ${info.prefix}__run(${args.join(', ')});`); out.push(` if (next == ${STATE_ERROR}) {`); out.push(` return ${compilation.errorField()};`); out.push(' }'); out.push(` ${compilation.currentField()} = (void*) (intptr_t) next;`); out.push(''); tmp = []; this.executeSpans(compilation, info, tmp); compilation.indent(out, tmp, ' '); out.push(' return 0;'); out.push('}'); return out.join('\n'); } private restartSpans(ctx: Compilation, info: frontend.IFrontendResult, out: string[]): void { if (info.spans.length === 0) { return; } out.push('/* restart spans */'); for (const span of info.spans) { const posField = ctx.spanPosField(span.index); out.push(`if (${posField} != NULL) {`); out.push(` ${posField} = (void*) ${ctx.posArg()};`); out.push('}'); } out.push(''); } private executeSpans(ctx: Compilation, info: frontend.IFrontendResult, out: string[]): void { if (info.spans.length === 0) { return; } out.push('/* execute spans */'); for (const span of info.spans) { const posField = ctx.spanPosField(span.index); let callback: string; if (span.callbacks.length === 1) { callback = ctx.buildCode(ctx.unwrapCode(span.callbacks[0]!)); } else { callback = `(${info.prefix}__span_cb) ` + ctx.spanCbField(span.index); callback = `(${callback})`; } const args = [ ctx.stateArg(), posField, `(const char*) ${ctx.endPosArg()}`, ]; out.push(`if (${posField} != NULL) {`); out.push(' int error;'); out.push(''); out.push(` error = ${callback}(${args.join(', ')});`); // TODO(indutny): de-duplicate this here and in SpanEnd out.push(' if (error != 0) {'); out.push(` ${ctx.errorField()} = error;`); out.push(` ${ctx.errorPosField()} = ${ctx.endPosArg()};`); out.push(' return error;'); out.push(' }'); out.push('}'); } out.push(''); } } llparse-7.3.0/src/implementation/c/node/000077500000000000000000000000001500517370100201455ustar00rootroot00000000000000llparse-7.3.0/src/implementation/c/node/base.ts000066400000000000000000000035651500517370100214400ustar00rootroot00000000000000import * as assert from 'assert'; import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { STATE_PREFIX, LABEL_PREFIX, } from '../constants'; export interface INodeEdge { readonly node: frontend.IWrap; readonly noAdvance: boolean; readonly value?: number; } export abstract class Node { protected cachedDecl: string | undefined; protected privCompilation: Compilation | undefined; constructor(public readonly ref: T) { } public build(compilation: Compilation): string { if (this.cachedDecl !== undefined) { return this.cachedDecl; } const res = STATE_PREFIX + this.ref.id.name; this.cachedDecl = res; this.privCompilation = compilation; const out: string[] = []; compilation.debug(out, `Entering node "${this.ref.id.originalName}" ("${this.ref.id.name}")`); this.doBuild(out); compilation.addState(res, out); return res; } protected get compilation(): Compilation { assert(this.privCompilation !== undefined); return this.privCompilation!; } protected prologue(out: string[]): void { const ctx = this.compilation; out.push(`if (${ctx.posArg()} == ${ctx.endPosArg()}) {`); const tmp: string[] = []; this.pause(tmp); this.compilation.indent(out, tmp, ' '); out.push('}'); } protected pause(out: string[]): void { out.push(`return ${this.cachedDecl};`); } protected tailTo(out: string[], edge: INodeEdge): void { const ctx = this.compilation; const target = ctx.unwrapNode(edge.node).build(ctx); if (!edge.noAdvance) { out.push(`${ctx.posArg()}++;`); } if (edge.value !== undefined) { out.push(`${ctx.matchVar()} = ${edge.value};`); } out.push(`goto ${LABEL_PREFIX}${target};`); } protected abstract doBuild(out: string[]): void; } llparse-7.3.0/src/implementation/c/node/consume.ts000066400000000000000000000024201500517370100221640ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Node } from './base'; export class Consume extends Node { public doBuild(out: string[]): void { const ctx = this.compilation; const index = ctx.stateField(this.ref.field); const ty = ctx.getFieldType(this.ref.field); let fieldTy: string; if (ty === 'i64') { fieldTy = 'uint64_t'; } else if (ty === 'i32') { fieldTy = 'uint32_t'; } else if (ty === 'i16') { fieldTy = 'uint16_t'; } else if (ty === 'i8') { fieldTy = 'uint8_t'; } else { throw new Error( `Unsupported type ${ty} of field ${this.ref.field} for consume node`); } out.push('size_t avail;'); out.push(`${fieldTy} need;`); out.push(''); out.push(`avail = ${ctx.endPosArg()} - ${ctx.posArg()};`); out.push(`need = ${index};`); // Note: `avail` or `need` are going to coerced to the largest // datatype needed to hold either of the values. out.push('if (avail >= need) {'); out.push(` p += need;`); out.push(` ${index} = 0;`); const tmp: string[] = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); out.push('}'); out.push(''); out.push(`${index} -= avail;`); this.pause(out); } } llparse-7.3.0/src/implementation/c/node/empty.ts000066400000000000000000000005021500517370100216500ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Node } from './base'; export class Empty extends Node { public doBuild(out: string[]): void { const otherwise = this.ref.otherwise!; if (!otherwise.noAdvance) { this.prologue(out); } this.tailTo(out, otherwise); } } llparse-7.3.0/src/implementation/c/node/error.ts000066400000000000000000000016341500517370100216520ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { STATE_ERROR } from '../constants'; import { Node } from './base'; class ErrorNode extends Node { protected storeError(out: string[]): void { const ctx = this.compilation; let hexCode: string; if (this.ref.code < 0) { hexCode = `-0x` + this.ref.code.toString(16); } else { hexCode = '0x' + this.ref.code.toString(16); } out.push(`${ctx.errorField()} = ${hexCode};`); out.push(`${ctx.reasonField()} = ${ctx.cstring(this.ref.reason)};`); out.push(`${ctx.errorPosField()} = (const char*) ${ctx.posArg()};`); } public doBuild(out: string[]): void { this.storeError(out); // Non-recoverable state out.push(`${this.compilation.currentField()} = ` + `(void*) (intptr_t) ${STATE_ERROR};`); out.push(`return ${STATE_ERROR};`); } } export { ErrorNode as Error }; llparse-7.3.0/src/implementation/c/node/index.ts000066400000000000000000000012101500517370100216160ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Consume } from './consume'; import { Empty } from './empty'; import { Error as ErrorNode } from './error'; import { Invoke } from './invoke'; import { Pause } from './pause'; import { Sequence } from './sequence'; import { Single } from './single'; import { SpanEnd } from './span-end'; import { SpanStart } from './span-start'; import { TableLookup } from './table-lookup'; export { Node } from './base'; class Error extends ErrorNode {} export default { Consume, Empty, Error, Invoke, Pause, Sequence, Single, SpanEnd, SpanStart, TableLookup, }; llparse-7.3.0/src/implementation/c/node/invoke.ts000066400000000000000000000017461500517370100220200ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Node } from './base'; export class Invoke extends Node { public doBuild(out: string[]): void { const ctx = this.compilation; const code = ctx.unwrapCode(this.ref.code); const codeDecl = ctx.buildCode(code); const args: string[] = [ ctx.stateArg(), ctx.posArg(), ctx.endPosArg(), ]; const signature = code.ref.signature; if (signature === 'value') { args.push(ctx.matchVar()); } out.push(`switch (${codeDecl}(${args.join(', ')})) {`); let tmp: string[]; for (const edge of this.ref.edges) { out.push(` case ${edge.code}:`); tmp = []; this.tailTo(tmp, { noAdvance: true, node: edge.node, value: undefined, }); ctx.indent(out, tmp, ' '); } out.push(' default:'); tmp = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); out.push('}'); } } llparse-7.3.0/src/implementation/c/node/pause.ts000066400000000000000000000010251500517370100216300ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { STATE_ERROR } from '../constants'; import { Error as ErrorNode } from './error'; export class Pause extends ErrorNode { public doBuild(out: string[]): void { const ctx = this.compilation; this.storeError(out); // Recoverable state const otherwise = ctx.unwrapNode(this.ref.otherwise!.node).build(ctx); out.push(`${ctx.currentField()} = ` + `(void*) (intptr_t) ${otherwise};`); out.push(`return ${STATE_ERROR};`); } } llparse-7.3.0/src/implementation/c/node/sequence.ts000066400000000000000000000025171500517370100223320ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { SEQUENCE_COMPLETE, SEQUENCE_MISMATCH, SEQUENCE_PAUSE, } from '../constants'; import { Node } from './base'; export class Sequence extends Node { public doBuild(out: string[]): void { const ctx = this.compilation; out.push('llparse_match_t match_seq;'); out.push(''); this.prologue(out); const matchSequence = ctx.getMatchSequence(this.ref.transform!, this.ref.select); out.push(`match_seq = ${matchSequence}(${ctx.stateArg()}, ` + `${ctx.posArg()}, ` + `${ctx.endPosArg()}, ${ctx.blob(this.ref.select)}, ` + `${this.ref.select.length});`); out.push('p = match_seq.current;'); let tmp: string[]; out.push('switch (match_seq.status) {'); out.push(` case ${SEQUENCE_COMPLETE}: {`); tmp = []; this.tailTo(tmp, { noAdvance: false, node: this.ref.edge!.node, value: this.ref.edge!.value, }); ctx.indent(out, tmp, ' '); out.push(' }'); out.push(` case ${SEQUENCE_PAUSE}: {`); tmp = []; this.pause(tmp); ctx.indent(out, tmp, ' '); out.push(' }'); out.push(` case ${SEQUENCE_MISMATCH}: {`); tmp = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); out.push(' }'); out.push('}'); } } llparse-7.3.0/src/implementation/c/node/single.ts000066400000000000000000000021421500517370100217750ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Node } from './base'; export class Single extends Node { public doBuild(out: string[]): void { const ctx = this.compilation; const otherwise = this.ref.otherwise!; this.prologue(out); const transform = ctx.unwrapTransform(this.ref.transform!); const current = transform.build(ctx, `*${ctx.posArg()}`); out.push(`switch (${current}) {`) this.ref.edges.forEach((edge) => { let ch: string; // Non-printable ASCII, or single-quote, or forward slash if (edge.key < 0x20 || edge.key > 0x7e || edge.key === 0x27 || edge.key === 0x5c) { ch = edge.key.toString(); } else { ch = `'${String.fromCharCode(edge.key)}'`; } out.push(` case ${ch}: {`); const tmp: string[] = []; this.tailTo(tmp, edge); ctx.indent(out, tmp, ' '); out.push(' }'); }); out.push(` default: {`); const tmp: string[] = []; this.tailTo(tmp, otherwise); ctx.indent(out, tmp, ' '); out.push(' }'); out.push(`}`); } } llparse-7.3.0/src/implementation/c/node/span-end.ts000066400000000000000000000030001500517370100222130ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { STATE_ERROR } from '../constants'; import { Node } from './base'; export class SpanEnd extends Node { public doBuild(out: string[]): void { out.push('const unsigned char* start;'); out.push('int err;'); out.push(''); const ctx = this.compilation; const field = this.ref.field; const posField = ctx.spanPosField(field.index); // Load start position out.push(`start = ${posField};`); // ...and reset out.push(`${posField} = NULL;`); // Invoke callback const callback = ctx.buildCode(ctx.unwrapCode(this.ref.callback)); out.push(`err = ${callback}(${ctx.stateArg()}, start, ${ctx.posArg()});`); out.push('if (err != 0) {'); const tmp: string[] = []; this.buildError(tmp, 'err'); ctx.indent(out, tmp, ' '); out.push('}'); const otherwise = this.ref.otherwise!; this.tailTo(out, otherwise); } private buildError(out: string[], code: string) { const ctx = this.compilation; out.push(`${ctx.errorField()} = ${code};`); const otherwise = this.ref.otherwise!; let resumePos = ctx.posArg(); if (!otherwise.noAdvance) { resumePos = `(${resumePos} + 1)`; } out.push(`${ctx.errorPosField()} = (const char*) ${resumePos};`); const resumptionTarget = ctx.unwrapNode(otherwise.node).build(ctx); out.push(`${ctx.currentField()} = ` + `(void*) (intptr_t) ${resumptionTarget};`); out.push(`return ${STATE_ERROR};`); } } llparse-7.3.0/src/implementation/c/node/span-start.ts000066400000000000000000000013161500517370100226120ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Node } from './base'; export class SpanStart extends Node { public doBuild(out: string[]): void { // Prevent spurious empty spans this.prologue(out); const ctx = this.compilation; const field = this.ref.field; const posField = ctx.spanPosField(field.index); out.push(`${posField} = (void*) ${ctx.posArg()};`); if (field.callbacks.length > 1) { const cbField = ctx.spanCbField(field.index); const callback = ctx.unwrapCode(this.ref.callback); out.push(`${cbField} = ${ctx.buildCode(callback)};`); } const otherwise = this.ref.otherwise!; this.tailTo(out, otherwise); } } llparse-7.3.0/src/implementation/c/node/table-lookup.ts000066400000000000000000000241631500517370100231210ustar00rootroot00000000000000import * as assert from 'assert'; import * as frontend from 'llparse-frontend'; import { Node } from './base'; const MAX_CHAR = 0xff; const TABLE_GROUP = 16; // _mm_cmpestri takes 8 ranges const SSE_RANGES_LEN = 16; // _mm_cmpestri takes 128bit input const SSE_RANGES_PAD = 16; const MAX_SSE_CALLS = 2; const MAX_NEON_RANGES = 6; const MAX_WASM_RANGES = 6; const SSE_ALIGNMENT = 16; interface ITable { readonly name: string; readonly declaration: ReadonlyArray; } export class TableLookup extends Node { public doBuild(out: string[]): void { const ctx = this.compilation; const table = this.buildTable(); for (const line of table.declaration) { out.push(line); } this.prologue(out); const transform = ctx.unwrapTransform(this.ref.transform!); // Try to vectorize nodes matching characters and looping to themselves // NOTE: `switch` below triggers when there is not enough characters in the // stream for vectorized processing. if (this.canVectorize()) { this.buildSSE(out); this.buildNeon(out); this.buildWASM(out); } const current = transform.build(ctx, `*${ctx.posArg()}`); out.push(`switch (${table.name}[(uint8_t) ${current}]) {`); for (const [ index, edge ] of this.ref.edges.entries()) { out.push(` case ${index + 1}: {`); const tmp: string[] = []; this.tailTo(tmp, { noAdvance: edge.noAdvance, node: edge.node, value: undefined, }); ctx.indent(out, tmp, ' '); out.push(' }'); } out.push(` default: {`); const tmp: string[] = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); out.push(' }'); out.push('}'); } private canVectorize(): boolean { // Transformation is not supported atm if (this.ref.transform && this.ref.transform.ref.name !== 'id') { return false; } if (this.ref.edges.length !== 1) { return false; } const edge = this.ref.edges[0]; if ( !edge || edge.node.ref !== this.ref ) { return false; } assert.strictEqual(edge.noAdvance, false); return true; } private buildRanges(edge: frontend.node.TableLookup["edges"][0]): number[] { // NOTE: keys are sorted const ranges: number[] = []; let first: number | undefined; let last: number | undefined; for (const key of edge.keys) { if (first === undefined) { first = key; } if (last === undefined) { last = key; } if (key - last > 1) { ranges.push(first, last); first = key; } last = key; } if (first !== undefined && last !== undefined) { ranges.push(first, last); } return ranges; } private buildSSE(out: string[]): boolean { const ctx = this.compilation; const edge = this.ref.edges[0]; assert(edge !== undefined); const ranges = this.buildRanges(edge); if (ranges.length === 0) { return false; } // Way too many calls would be required if (ranges.length > MAX_SSE_CALLS * SSE_RANGES_LEN) { return false; } out.push('#ifdef __SSE4_2__'); out.push(`if (${ctx.endPosArg()} - ${ctx.posArg()} >= 16) {`); out.push(' __m128i ranges;'); out.push(' __m128i input;'); out.push(' int match_len;'); out.push(''); out.push(' /* Load input */'); out.push(` input = _mm_loadu_si128((__m128i const*) ${ctx.posArg()});`); for (let off = 0; off < ranges.length; off += SSE_RANGES_LEN) { const subRanges = ranges.slice(off, off + SSE_RANGES_LEN); let paddedRanges = subRanges.slice(); while (paddedRanges.length < SSE_RANGES_PAD) { paddedRanges.push(0); } const blob = ctx.blob(Buffer.from(paddedRanges), SSE_ALIGNMENT); out.push(` ranges = _mm_loadu_si128((__m128i const*) ${blob});`); out.push(''); out.push(' /* Find first character that does not match `ranges` */'); out.push(` match_len = _mm_cmpestri(ranges, ${subRanges.length},`); out.push(' input, 16,'); out.push(' _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES |'); out.push(' _SIDD_NEGATIVE_POLARITY);'); out.push(''); out.push(' if (match_len != 0) {'); out.push(` ${ctx.posArg()} += match_len;`); const tmp: string[] = []; this.tailTo(tmp, { noAdvance: true, node: edge.node, }); ctx.indent(out, tmp, ' '); out.push(' }'); } { const tmp: string[] = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); } out.push('}'); out.push('#endif /* __SSE4_2__ */'); return true; } private buildNeon(out: string[]): boolean { const ctx = this.compilation; const edge = this.ref.edges[0]; assert(edge !== undefined); const ranges = this.buildRanges(edge); if (ranges.length === 0) { return false; } // Way too many calls would be required if (ranges.length > MAX_NEON_RANGES) { return false; } out.push('#ifdef __ARM_NEON__'); out.push(`while (${ctx.endPosArg()} - ${ctx.posArg()} >= 16) {`); out.push(' uint8x16_t input;'); out.push(' uint8x16_t single;'); out.push(' uint8x16_t mask;'); out.push(' uint8x8_t narrow;'); out.push(' uint64_t match_mask;'); out.push(' int match_len;'); out.push(''); out.push(' /* Load input */'); out.push(` input = vld1q_u8(${ctx.posArg()});`); out.push(' /* Find first character that does not match `ranges` */'); function v128(value: number): string { return `vdupq_n_u8(${ctx.toChar(value)})`; } for (let off = 0; off < ranges.length; off += 2) { const start = ranges[off]; const end = ranges[off + 1]; assert(start !== undefined); assert(end !== undefined); // Same character, equality is sufficient (and faster) if (start === end) { out.push(` single = vceqq_u8(input, ${v128(start)});`); } else { out.push(` single = vandq_u16(`); out.push(` vcgeq_u8(input, ${v128(start)}),`); out.push(` vcleq_u8(input, ${v128(end)})`); out.push(' );'); } if (off === 0) { out.push(' mask = single;'); } else { out.push(' mask = vorrq_u16(mask, single);'); } } // https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon out.push(' narrow = vshrn_n_u16(mask, 4);'); out.push(' match_mask = ~vget_lane_u64(vreinterpret_u64_u8(narrow), 0);'); out.push(' match_len = __builtin_ctzll(match_mask) >> 2;'); out.push(' if (match_len != 16) {'); out.push(` ${ctx.posArg()} += match_len;`); { const tmp: string[] = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); } out.push(' }'); out.push(` ${ctx.posArg()} += 16;`); out.push('}'); out.push(`if (${ctx.posArg()} == ${ctx.endPosArg()}) {`); { const tmp: string[] = []; this.pause(tmp); this.compilation.indent(out, tmp, ' '); } out.push('}'); out.push('#endif /* __ARM_NEON__ */'); return true; } private buildWASM(out: string[]): boolean { const ctx = this.compilation; const edge = this.ref.edges[0]; assert(edge !== undefined); const ranges = this.buildRanges(edge); if (ranges.length === 0) { return false; } // Way too many calls would be required if (ranges.length > MAX_WASM_RANGES) { return false; } out.push('#ifdef __wasm_simd128__'); out.push(`while (${ctx.endPosArg()} - ${ctx.posArg()} >= 16) {`); out.push(' v128_t input;'); out.push(' v128_t mask;'); out.push(' v128_t single;'); out.push(' int match_len;'); out.push(''); out.push(' /* Load input */'); out.push(` input = wasm_v128_load(${ctx.posArg()});`); out.push(' /* Find first character that does not match `ranges` */'); function v128(value: number): string { return `wasm_u8x16_const_splat(${ctx.toChar(value)})`; } for (let off = 0; off < ranges.length; off += 2) { const start = ranges[off]; const end = ranges[off + 1]; assert(start !== undefined); assert(end !== undefined); // Same character, equality is sufficient (and faster) if (start === end) { out.push(` single = wasm_i8x16_eq(input, ${v128(start)});`); } else { out.push(` single = wasm_v128_and(`); out.push(` wasm_i8x16_ge(input, ${v128(start)}),`); out.push(` wasm_i8x16_le(input, ${v128(end)})`); out.push(' );'); } if (off === 0) { out.push(' mask = single;'); } else { out.push(' mask = wasm_v128_or(mask, single);'); } } out.push(' match_len = __builtin_ctz('); out.push(' ~wasm_i8x16_bitmask(mask)'); out.push(' );'); out.push(' if (match_len != 16) {'); out.push(` ${ctx.posArg()} += match_len;`); { const tmp: string[] = []; this.tailTo(tmp, this.ref.otherwise!); ctx.indent(out, tmp, ' '); } out.push(' }'); out.push(` ${ctx.posArg()} += 16;`); out.push('}'); out.push(`if (${ctx.posArg()} == ${ctx.endPosArg()}) {`); { const tmp: string[] = []; this.pause(tmp); this.compilation.indent(out, tmp, ' '); } out.push('}'); out.push('#endif /* __wasm_simd128__ */'); return true; } private buildTable(): ITable { const table: number[] = new Array(MAX_CHAR + 1).fill(0); for (const [ index, edge ] of this.ref.edges.entries()) { edge.keys.forEach((key) => { assert.strictEqual(table[key], 0); table[key] = index + 1; }); } const lines = [ 'static uint8_t lookup_table[] = {', ]; for (let i = 0; i < table.length; i += TABLE_GROUP) { let line = ` ${table.slice(i, i + TABLE_GROUP).join(', ')}`; if (i + TABLE_GROUP < table.length) { line += ','; } lines.push(line); } lines.push('};'); return { name: 'lookup_table', declaration: lines, }; } } llparse-7.3.0/src/implementation/c/transform/000077500000000000000000000000001500517370100212335ustar00rootroot00000000000000llparse-7.3.0/src/implementation/c/transform/base.ts000066400000000000000000000004311500517370100225130ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; export abstract class Transform { constructor(public readonly ref: T) { } public abstract build(ctx: Compilation, value: string): string; } llparse-7.3.0/src/implementation/c/transform/id.ts000066400000000000000000000004561500517370100222040ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Transform } from './base'; export class ID extends Transform { public build(ctx: Compilation, value: string): string { // Identity transformation return value; } } llparse-7.3.0/src/implementation/c/transform/index.ts000066400000000000000000000003201500517370100227050ustar00rootroot00000000000000import { ID } from './id'; import { ToLower } from './to-lower'; import { ToLowerUnsafe } from './to-lower-unsafe'; export { Transform } from './base'; export default { ID, ToLower, ToLowerUnsafe, }; llparse-7.3.0/src/implementation/c/transform/to-lower-unsafe.ts000066400000000000000000000004651500517370100246370ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Transform } from './base'; export class ToLowerUnsafe extends Transform { public build(ctx: Compilation, value: string): string { return `((${value}) | 0x20)`; } } llparse-7.3.0/src/implementation/c/transform/to-lower.ts000066400000000000000000000005521500517370100233550ustar00rootroot00000000000000import * as frontend from 'llparse-frontend'; import { Compilation } from '../compilation'; import { Transform } from './base'; export class ToLower extends Transform { public build(ctx: Compilation, value: string): string { return `((${value}) >= 'A' && (${value}) <= 'Z' ? ` + `(${value} | 0x20) : (${value}))`; } } llparse-7.3.0/test/000077500000000000000000000000001500517370100141415ustar00rootroot00000000000000llparse-7.3.0/test/code-test.ts000066400000000000000000000106631500517370100164060ustar00rootroot00000000000000import { LLParse } from '../src/api'; import { build, NUM_SELECT, printOff } from './fixtures'; describe('llparse/code', () => { let p: LLParse; beforeEach(() => { p = new LLParse(); }); describe('`.mulAdd()`', () => { it('should operate normally', async () => { const start = p.node('start'); const dot = p.node('dot'); p.property('i64', 'counter'); const is1337 = p.invoke(p.code.load('counter'), { 1337: printOff(p, p.invoke(p.code.update('counter', 0), start)), }, p.error(1, 'Invalid result')); const count = p.invoke(p.code.mulAdd('counter', { base: 10 }), start); start .select(NUM_SELECT, count) .otherwise(dot); dot .match('.', is1337) .otherwise(p.error(1, 'Unexpected')); const binary = await build(p, start, 'mul-add'); await binary.check('1337.', 'off=5\n'); }); it('should operate fail on overflow', async () => { const start = p.node('start'); p.property('i8', 'counter'); const count = p.invoke(p.code.mulAdd('counter', { base: 10 }), { 1: printOff(p, start), }, start); start .select(NUM_SELECT, count) .otherwise(p.error(1, 'Unexpected')); const binary = await build(p, start, 'mul-add-overflow'); await binary.check('1111', 'off=4\n'); }); it('should operate fail on greater than max', async () => { const start = p.node('start'); p.property('i64', 'counter'); const count = p.invoke(p.code.mulAdd('counter', { base: 10, max: 1000, }), { 1: printOff(p, start), }, start); start .select(NUM_SELECT, count) .otherwise(p.error(1, 'Unexpected')); const binary = await build(p, start, 'mul-add-max-overflow'); await binary.check('1111', 'off=4\n'); }); }); describe('`.update()`', () => { it('should operate normally', async () => { const start = p.node('start'); p.property('i64', 'counter'); const update = p.invoke(p.code.update('counter', 42)); start .skipTo(update); update .otherwise(p.invoke(p.code.load('counter'), { 42: printOff(p, start), }, p.error(1, 'Unexpected'))); const binary = await build(p, start, 'update'); await binary.check('.', 'off=1\n'); }); }); describe('`.isEqual()`', () => { it('should operate normally', async () => { const start = p.node('start'); p.property('i64', 'counter'); const check = p.invoke(p.code.isEqual('counter', 1), { 0: printOff(p, start), 1: start, }, p.error(1, 'Unexpected')); start .select(NUM_SELECT, p.invoke(p.code.store('counter'), check)) .otherwise(p.error(1, 'Unexpected')); const binary = await build(p, start, 'is-equal'); await binary.check('010', 'off=1\noff=3\n'); }); }); describe('`.or()`/`.and()`/`.test()`', () => { it('should set and retrieve bits', async () => { const start = p.node('start'); const test = p.node('test'); p.property('i64', 'flag'); start .match('1', p.invoke(p.code.or('flag', 1), start)) .match('2', p.invoke(p.code.or('flag', 2), start)) .match('4', p.invoke(p.code.or('flag', 4), start)) // Reset .match('r', p.invoke(p.code.update('flag', 0), start)) // Partial Reset .match('p', p.invoke(p.code.and('flag', ~1), start)) // Test .match('-', test) .otherwise(p.error(1, 'start')); test .match('1', p.invoke(p.code.test('flag', 1), { 0: test, 1: printOff(p, test), }, p.error(2, 'test-1'))) .match('2', p.invoke(p.code.test('flag', 2), { 0: test, 1: printOff(p, test), }, p.error(3, 'test-2'))) .match('4', p.invoke(p.code.test('flag', 4), { 0: test, 1: printOff(p, test), }, p.error(4, 'test-3'))) .match('7', p.invoke(p.code.test('flag', 7), { 0: test, 1: printOff(p, test), }, p.error(5, 'test-7'))) // Restart .match('.', start) .otherwise(p.error(6, 'test')); const binary = await build(p, start, 'or-test'); await binary.check('1-124.2-1247.4-1247.r4-124.r12p-12', [ 'off=3', 'off=9', 'off=10', 'off=16', 'off=17', 'off=18', 'off=19', 'off=26', 'off=34', ]); }); }); }); llparse-7.3.0/test/compiler-test.ts000066400000000000000000000172061500517370100173060ustar00rootroot00000000000000import { LLParse } from '../src/api'; import { ALPHA, build, NUM, NUM_SELECT, printMatch, printOff, } from './fixtures'; describe('llparse/Compiler', () => { let p: LLParse; beforeEach(() => { p = new LLParse(); }); it('should compile simple parser', async () => { const start = p.node('start'); start.match(' ', start); start.match('HTTP', printOff(p, start)); start.select({ CONNECT: 6, DELETE: 4, GET: 1, HEAD: 0, OPTIONS: 5, PATCH: 8, POST: 2, PUT: 3, TRACE: 7, }, printMatch(p, start)); start.otherwise(p.error(3, 'Invalid word')); const binary = await build(p, start, 'simple'); await binary.check('GET', 'off=3 match=1\n'); }); it('should optimize shallow select', async () => { const start = p.node('start'); start.select(NUM_SELECT, printMatch(p, start)); start.otherwise(p.error(3, 'Invalid word')); const binary = await build(p, start, 'shallow'); await binary.check('012', 'off=1 match=0\noff=2 match=1\noff=3 match=2\n'); }); it('should support key-value select', async () => { const start = p.node('start'); start.select('0', 0, printMatch(p, start)); start.select('1', 1, printMatch(p, start)); start.select('2', 2, printMatch(p, start)); start.otherwise(p.error(3, 'Invalid word')); const binary = await build(p, start, 'kv-select'); await binary.check('012', 'off=1 match=0\noff=2 match=1\noff=3 match=2\n'); }); it('should support multi-match', async () => { const start = p.node('start'); start.match([ ' ', '\t', '\r', '\n' ], start); start.select({ A: 0, B: 1, }, printMatch(p, start)); start.otherwise(p.error(3, 'Invalid word')); const binary = await build(p, start, 'multi-match'); await binary.check( 'A B\t\tA\r\nA', 'off=1 match=0\noff=3 match=1\noff=6 match=0\noff=9 match=0\n'); }); it('should support numeric-match', async () => { const start = p.node('start'); start.match(32, start); start.select({ A: 0, B: 1, }, printMatch(p, start)); start.otherwise(p.error(3, 'Invalid word')); const binary = await build(p, start, 'multi-match'); await binary.check( 'A B A A', 'off=1 match=0\noff=3 match=1\noff=6 match=0\noff=9 match=0\n'); }); it('should support custom state properties', async () => { const start = p.node('start'); const error = p.error(3, 'Invalid word'); p.property('i8', 'custom'); const second = p.invoke(p.code.load('custom'), { 0: p.invoke(p.code.match('llparse__print_zero'), { 0: start }, error), 1: p.invoke(p.code.match('llparse__print_one'), { 0: start }, error), }, error); start .select({ 0: 0, 1: 1, }, p.invoke(p.code.store('custom'), second)) .otherwise(error); const binary = await build(p, start, 'custom-prop'); await binary.check('0110', 'off=1 0\noff=2 1\noff=3 1\noff=4 0\n'); }); it('should return error code/reason', async () => { const start = p.node('start'); start.match('a', start); start.otherwise(p.error(42, 'some reason')); const binary = await build(p, start, 'error'); await binary.check('aab', 'off=2 error code=42 reason="some reason"\n'); }); it('should not merge `.match()` with `.peek()`', async () => { const maybeCr = p.node('maybeCr'); const lf = p.node('lf'); maybeCr.peek('\n', lf); maybeCr.match('\r', lf); maybeCr.otherwise(p.error(1, 'error')); lf.match('\n', printOff(p, maybeCr)); lf.otherwise(p.error(2, 'error')); const binary = await build(p, maybeCr, 'no-merge'); await binary.check('\r\n\n', 'off=2\noff=3\n'); }); describe('`.match()`', () => { it('should compile to a single-bit table-lookup node', async () => { const start = p.node('start'); start .match(ALPHA, start) .skipTo(printOff(p, start)); // TODO(indutny): validate compilation result? const binary = await build(p, start, 'match-bit-check'); await binary.check('pecan.is.dead.', 'off=6\noff=9\noff=14\n'); }); it('should compile to a multi-bit table-lookup node', async () => { const start = p.node('start'); const another = p.node('another'); start .match(ALPHA, start) .peek(NUM, another) .skipTo(printOff(p, start)); another .match(NUM, another) .otherwise(start); // TODO(indutny): validate compilation result? const binary = await build(p, start, 'match-multi-bit-check'); await binary.check('pecan.135.is.dead.', 'off=6\noff=10\noff=13\noff=18\n'); }); it('should not overflow on signed char in table-lookup node', async () => { const start = p.node('start'); start .match(ALPHA, start) .match([ 0xc3, 0xbc ], start) .skipTo(printOff(p, start)); // TODO(indutny): validate compilation result? const binary = await build(p, start, 'match-bit-check'); await binary.check('Düsseldorf.', 'off=12\n'); }); it('should match single quotes and forward slashes', async () => { const start = p.node('start'); start .match('\'', printOff(p, start)) .match('\\', printOff(p, start)) .otherwise(p.error(3, 'Invalid char')); // TODO(indutny): validate compilation result? const binary = await build(p, start, 'escape-char'); await binary.check('\\\'', 'off=1\noff=2\n'); }); it('should hit SSE4.2 optimization for table-lookup', async () => { const start = p.node('start'); start .match(ALPHA, start) .skipTo(printOff(p, start)); // TODO(indutny): validate compilation result? const binary = await build(p, start, 'match-bit-check-sse'); await binary.check('abcdabcdabcdabcdabcdabcdabcd.abcd.', 'off=29\noff=34\n'); }); it('should compile overlapping matches', async () => { const start = p.node('start'); start.select({ aa: 1, aab: 2, }, printMatch(p, start)); start.otherwise(p.error(3, 'Invalid word')); const binary = await build(p, start, 'overlapping-matches'); await binary.check('aaaabaa', 'off=2 match=1\noff=5 match=2\n'); }); }); describe('`.peek()`', () => { it('should not advance position', async () => { const start = p.node('start'); const ab = p.node('ab'); const error = p.error(3, 'Invalid word'); start .peek([ 'a', 'b' ], ab) .otherwise(error); ab .match([ 'a', 'b' ], printOff(p, start)) .otherwise(error); const binary = await build(p, start, 'peek'); await binary.check('ab', 'off=1\noff=2\n'); }); }); describe('`.otherwise()`', () => { it('should not advance position by default', async () => { const a = p.node('a'); const b = p.node('b'); a .match('A', a) .otherwise(b); b .match('B', printOff(p, b)) .skipTo(a); const binary = await build(p, a, 'otherwise-noadvance'); await binary.check('AABAB', 'off=3\noff=5\n'); }); it('should advance when it is `.skipTo()`', async () => { const start = p.node('start'); start .match(' ', printOff(p, start)) .skipTo(start); const binary = await build(p, start, 'otherwise-skip'); await binary.check('HELLO WORLD', 'off=6\n'); }); it('should skip everything with `.skipTo()`', async () => { const start = p.node('start'); start .skipTo(start); const binary = await build(p, start, 'all-skip'); await binary.check('HELLO WORLD', '\n'); }); }); }); llparse-7.3.0/test/consume-test.ts000066400000000000000000000032771500517370100171500ustar00rootroot00000000000000import { LLParse } from '../src/api'; import { build, NUM_SELECT, printOff } from './fixtures'; describe('llparse/consume', () => { let p: LLParse; beforeEach(() => { p = new LLParse(); }); it('should consume bytes with i8 field', async () => { p.property('i8', 'to_consume'); const start = p.node('start'); const consume = p.consume('to_consume'); start.select(NUM_SELECT, p.invoke(p.code.store('to_consume'), consume)); start .otherwise(p.error(1, 'unexpected')); consume .otherwise(printOff(p, start)); const binary = await build(p, start, 'consume'); await binary.check('3aaa2bb1a01b', 'off=4\noff=7\noff=9\noff=10\noff=12\n'); }); it('should consume bytes with i64 field', async () => { p.property('i64', 'to_consume'); const start = p.node('start'); const consume = p.consume('to_consume'); start.select(NUM_SELECT, p.invoke(p.code.store('to_consume'), consume)); start .otherwise(p.error(1, 'unexpected')); consume .otherwise(printOff(p, start)); const binary = await build(p, start, 'consume-i64'); await binary.check('3aaa2bb1a01b', 'off=4\noff=7\noff=9\noff=10\noff=12\n'); }); it('should consume bytes with untruncated i64 field', async () => { p.property('i64', 'to_consume'); const start = p.node('start'); const consume = p.consume('to_consume'); start .select( NUM_SELECT, p.invoke(p.code.mulAdd('to_consume', { base: 10 }), start) ) .skipTo(consume); consume .otherwise(printOff(p, start)); const binary = await build(p, start, 'consume-untruncated-i64'); await binary.check('4294967297.xxxxxxxx', '\n'); }); }); llparse-7.3.0/test/fixtures/000077500000000000000000000000001500517370100160125ustar00rootroot00000000000000llparse-7.3.0/test/fixtures/extra.c000066400000000000000000000034471500517370100173110ustar00rootroot00000000000000#include "fixture.h" int llparse__print_zero(llparse_t* s, const char* p, const char* endp) { if (llparse__in_bench) return 0; llparse__print(p, endp, "0"); return 0; } int llparse__print_one(llparse_t* s, const char* p, const char* endp) { if (llparse__in_bench) return 0; llparse__print(p, endp, "1"); return 0; } int llparse__print_off(llparse_t* s, const char* p, const char* endp) { if (llparse__in_bench) return 0; llparse__print(p, endp, ""); return 0; } int llparse__print_match(llparse_t* s, const char* p, const char* endp, int value) { if (llparse__in_bench) return 0; llparse__print(p, endp, "match=%d", value); return 0; } int llparse__on_dot(llparse_t* s, const char* p, const char* endp) { if (llparse__in_bench) return 0; return llparse__print_span("dot", p, endp); } int llparse__on_dash(llparse_t* s, const char* p, const char* endp) { if (llparse__in_bench) return 0; return llparse__print_span("dash", p, endp); } int llparse__on_underscore(llparse_t* s, const char* p, const char* endp) { if (llparse__in_bench) return 0; return llparse__print_span("underscore", p, endp); } /* A span callback, really */ int llparse__please_fail(llparse_t* s, const char* p, const char* endp) { s->reason = "please fail"; if (llparse__in_bench) return 1; return 1; } /* A span callback, really */ static int llparse__pause_once_counter; int llparse__pause_once(llparse_t* s, const char* p, const char* endp) { if (!llparse__in_bench) llparse__print_span("pause", p, endp); if (llparse__pause_once_counter != 0) return 0; llparse__pause_once_counter = 1; return LLPARSE__ERROR_PAUSE; } void llparse__test_init(llparse_t* p) { llparse__pause_once_counter = 0; } llparse-7.3.0/test/fixtures/index.ts000066400000000000000000000030101500517370100174630ustar00rootroot00000000000000import { source } from 'llparse-frontend'; import { Fixture, FixtureResult } from 'llparse-test-fixture'; import * as path from 'path'; import { LLParse } from '../../src/api'; export { ERROR_PAUSE } from 'llparse-test-fixture'; const fixtures = new Fixture({ buildDir: path.join(__dirname, '..', 'tmp'), extra: [ '-msse4.2', '-DLLPARSE__TEST_INIT=llparse__test_init', path.join(__dirname, 'extra.c'), ], }); export function build(llparse: LLParse, node: source.node.Node, outFile: string): Promise { return fixtures.build(llparse.build(node, { c: { header: outFile, }, }), outFile); } export function printMatch(p: LLParse, next: source.node.Node): source.node.Node { const code = p.code.value('llparse__print_match'); const res = p.invoke(code, next); return res; } export function printOff(p: LLParse, next: source.node.Node): source.node.Node { const code = p.code.match('llparse__print_off'); return p.invoke(code, next); } export const NUM_SELECT: { readonly [key: string]: number } = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, }; export const NUM: ReadonlyArray = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ]; export const ALPHA: ReadonlyArray = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ]; llparse-7.3.0/test/resumption-test.ts000066400000000000000000000023151500517370100176740ustar00rootroot00000000000000import { LLParse } from '../src/api'; import { build, ERROR_PAUSE, printOff } from './fixtures'; describe('llparse/resumption', () => { let p: LLParse; beforeEach(() => { p = new LLParse(); }); it('should resume after span end pause', async () => { const start = p.node('start'); const a = p.node('a'); const span = p.span(p.code.span('llparse__pause_once')); start .peek('a', span.start(a)) .skipTo(start); a .match('a', a) .otherwise(span.end(start)); const binary = await build(p, start, 'resume-span'); await binary.check('baaab', new RegExp( '^(' + 'off=\\d+ pause\\noff=1 len=3 span\\[pause\\]="aaa"' + '|' + 'off=1 len=3 span\\[pause\\]="aaa"\noff=4 pause' + ')\\n$' , 'g')); }); it('should resume after `pause` node', async () => { const start = p.node('start'); const pause = p.pause(ERROR_PAUSE, 'paused'); start .match('p', pause) .skipTo(start); pause .otherwise(printOff(p, start)); const binary = await build(p, start, 'resume-pause'); await binary.check('..p....p..', 'off=3 pause\noff=3\noff=8 pause\noff=8\n'); }); }); llparse-7.3.0/test/span-test.ts000066400000000000000000000050541500517370100164330ustar00rootroot00000000000000import { LLParse } from '../src/api'; import { build } from './fixtures'; describe('llparse/spans', () => { let p: LLParse; beforeEach(() => { p = new LLParse(); }); it('should invoke span callback', async () => { const start = p.node('start'); const dot = p.node('dot'); const dash = p.node('dash'); const underscore = p.node('underscore'); const span = { dash: p.span(p.code.span('llparse__on_dash')), dot: p.span(p.code.span('llparse__on_dot')), underscore: p.span(p.code.span('llparse__on_underscore')), }; start.otherwise(span.dot.start(dot)); dot .match('.', dot) .peek('-', span.dash.start(dash)) .peek('_', span.underscore.start(underscore)) .skipTo(span.dot.end(start)); dash .match('-', dash) .otherwise(span.dash.end(dot)); underscore .match('_', underscore) .otherwise(span.underscore.end(dot)); const binary = await build(p, start, 'span'); await binary.check('..--..__..', 'off=2 len=2 span[dash]="--"\n' + 'off=6 len=2 span[underscore]="__"\n' + 'off=0 len=10 span[dot]="..--..__.."\n'); }); it('should return error', async () => { const start = p.node('start'); const dot = p.node('dot'); const span = { pleaseFail: p.span(p.code.span('llparse__please_fail')), }; start.otherwise(span.pleaseFail.start(dot)); dot .match('.', dot) .skipTo(span.pleaseFail.end(start)); const binary = await build(p, start, 'span-error'); await binary.check( '....a', /off=\d+ error code=1 reason="please fail"\n/); }); it('should return error at `executeSpans()`', async () => { const start = p.node('start'); const dot = p.node('dot'); const span = { pleaseFail: p.span(p.code.span('llparse__please_fail')), }; start.otherwise(span.pleaseFail.start(dot)); dot .match('.', dot) .skipTo(span.pleaseFail.end(start)); const binary = await build(p, start, 'span-error-execute'); await binary.check( '.........', /off=9 error code=1 reason="please fail"\n/, { scan: 100 }); }); it('should not invoke spurious span callback', async () => { const start = p.node('start'); const dot = p.node('dot'); const span = p.span(p.code.span('llparse__on_dot')); start .match('hello', span.start(dot)) .skipTo(start); dot .match('.', dot) .skipTo(span.end(start)); const binary = await build(p, start, 'span-spurious'); await binary.check('hello', [ '' ]); }); }); llparse-7.3.0/test/transform-test.ts000066400000000000000000000020371500517370100175030ustar00rootroot00000000000000import { LLParse } from '../src/api'; import { build, printMatch, printOff } from './fixtures'; describe('llparse/transform', () => { let p: LLParse; beforeEach(() => { p = new LLParse(); }); it('should apply transformation before the match', async () => { const start = p.node('start'); start .transform(p.transform.toLowerUnsafe()) .match('connect', printOff(p, start)) .match('close', printOff(p, start)) .otherwise(p.error(1, 'error')); const binary = await build(p, start, 'transform-lower'); await binary.check('connectCLOSEcOnNeCt', 'off=7\noff=12\noff=19\n'); }); it('should apply safe `toLower()` transformation', async () => { const start = p.node('start'); start .transform(p.transform.toLower()) .select({ 'a-b': 1, 'a\rb': 2, }, printMatch(p, start)) .otherwise(p.error(1, 'error')); const binary = await build(p, start, 'transform-safe-lower'); await binary.check('A-ba\rB', 'off=3 match=1\noff=6 match=2\n'); }); }); llparse-7.3.0/tsconfig.eslint.json000066400000000000000000000001171500517370100171650ustar00rootroot00000000000000{ "extends": "./tsconfig.json", "include": [ "**/*.ts" ] } llparse-7.3.0/tsconfig.json000066400000000000000000000005071500517370100156730ustar00rootroot00000000000000{ "compilerOptions": { "strict": true, "target": "es2022", "module": "commonjs", "moduleResolution": "node", "outDir": "./lib", "declaration": true, "pretty": true, "sourceMap": true, "noUncheckedIndexedAccess": true, "noUnusedLocals": true }, "include": [ "src/**/*.ts" ] }