├── .eslintrc.json ├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── Makefile ├── bench └── bench.js ├── changelog.md ├── package-lock.json ├── package.json ├── readme.md ├── src ├── errors.ts ├── index.ts ├── money.ts └── util.ts ├── test ├── money-compare.ts ├── money.ts ├── util-bigint-to-fixed.ts └── util-rounding.ts └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "es6": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended" 11 | ], 12 | "globals": { 13 | "Atomics": "readonly", 14 | "SharedArrayBuffer": "readonly" 15 | }, 16 | "parser": "@typescript-eslint/parser", 17 | "parserOptions": { 18 | "ecmaVersion": 2018, 19 | "sourceType": "module" 20 | }, 21 | "plugins": [ 22 | "@typescript-eslint" 23 | ], 24 | "rules": { 25 | "indent": ["error", 2, { 26 | "SwitchCase": 1 27 | }], 28 | "linebreak-style": ["error", "unix"], 29 | "no-constant-condition": ["error", { 30 | "checkLoops": false 31 | }], 32 | "quotes": ["error", "single", 33 | { 34 | "allowTemplateLiterals": false, 35 | "avoidEscape": true 36 | } 37 | ], 38 | "semi": ["error", "always"], 39 | "no-trailing-spaces": "error", 40 | "eol-last": "error", 41 | "@typescript-eslint/ban-ts-comment": ["error", 42 | { 43 | "ts-expect-error": "allow-with-description" 44 | } 45 | ], 46 | "@typescript-eslint/ban-tslint-comment": "error", 47 | "@typescript-eslint/consistent-type-assertions": ["error", { 48 | "assertionStyle": "as", 49 | "objectLiteralTypeAssertions": "never" 50 | }], 51 | "@typescript-eslint/member-delimiter-style": "error", 52 | "@typescript-eslint/no-inferrable-types": "off", 53 | "@typescript-eslint/no-explicit-any" : 0, 54 | "@typescript-eslint/no-for-in-array": "error", 55 | "@typescript-eslint/no-invalid-void-type": "error", 56 | "@typescript-eslint/no-namespace": "error", 57 | "@typescript-eslint/no-non-null-asserted-optional-chain": "error", 58 | "@typescript-eslint/no-unused-vars": ["error", { 59 | "ignoreRestSiblings": true, 60 | "args": "none" 61 | }], 62 | "@typescript-eslint/prefer-for-of": ["error"], 63 | "@typescript-eslint/prefer-ts-expect-error": ["error"], 64 | "no-console": ["error"] 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [16.x, 18.x, 20.x, 21.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - run: npm ci 29 | - run: npm run build --if-present 30 | - run: npm test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /.nyc_output 3 | .*.swp 4 | 5 | dist/ 6 | browser/ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-2021 Evert Pot 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | project:=bigint-money 2 | export PATH:=./node_modules/.bin/:$(PATH) 3 | 4 | .PHONY: build 5 | build: tsbuild 6 | 7 | .PHONY: clean 8 | clean: 9 | rm -r browser/ 10 | rm -r dist/ 11 | 12 | .PHONY: test 13 | test: lint 14 | npx tsx --test test/*.ts 15 | 16 | .PHONY: test-debug 17 | test-debug: 18 | mocha --inspect-brk 19 | 20 | .PHONY:lint 21 | lint: 22 | eslint --quiet 'src/*.ts' 'test/*.ts' 23 | 24 | .PHONY:lint-fix 25 | lint-fix: fix 26 | 27 | .PHONY:fix 28 | fix: 29 | eslint --quiet 'src/**/*.ts' 'test/**/*.ts' --fix 30 | 31 | .PHONY: tsbuild 32 | tsbuild: 33 | tsc 34 | 35 | .PHONY: watch 36 | watch: 37 | tsc --watch 38 | -------------------------------------------------------------------------------- /bench/bench.js: -------------------------------------------------------------------------------- 1 | const bigintMoney = require('bigint-money'); 2 | const BigMoney = require('bigmoney.js'); 3 | const moneyMath = require('money-math'); 4 | 5 | const benchmarks = [ 6 | 7 | { 8 | name: 'bigint-money', 9 | test: function(ledger) { 10 | 11 | let m = new bigintMoney.Money(0, 'USD'); 12 | for(const transaction of ledger) { 13 | 14 | switch(transaction[0]) { 15 | case '+' : 16 | m = m.add(transaction[1]); 17 | break; 18 | case '*' : 19 | m = m.multiply(transaction[1]); 20 | break; 21 | } 22 | 23 | } 24 | 25 | return m.toFixed(2); 26 | 27 | } 28 | 29 | }, 30 | 31 | { 32 | name: 'big-money', 33 | test: function(ledger) { 34 | 35 | let m = new BigMoney(0, 'USD'); 36 | for(const transaction of ledger) { 37 | 38 | switch(transaction[0]) { 39 | case '+' : 40 | m = m.plus(transaction[1]); 41 | break; 42 | case '*' : 43 | m = m.times(transaction[1]); 44 | break; 45 | } 46 | 47 | } 48 | 49 | return m.format() 50 | 51 | } 52 | 53 | } 54 | 55 | ]; 56 | 57 | const ledger = []; 58 | 59 | for(let ii = 0; ii < 1000000; ii++ ) { 60 | 61 | if (ii % 100 === 0) { 62 | 63 | // interest 64 | ledger.push(['*', '0.025']); 65 | 66 | } else { 67 | 68 | ledger.push(['+', (Math.random() * 1000000).toFixed(3)]); 69 | 70 | } 71 | 72 | } 73 | 74 | function runBenchmark(bench) { 75 | 76 | console.log(bench.name); 77 | const start = Date.now(); 78 | 79 | const result = bench.test(ledger); 80 | const end = Date.now(); 81 | 82 | console.log('time: ', end-start); 83 | console.log('result: ', result); 84 | 85 | 86 | } 87 | 88 | // runBenchmark(benchmarks[0]); 89 | runBenchmark(benchmarks[1]); 90 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 2.0.0 (2024-04-21) 5 | ------------------ 6 | 7 | * Full ESM conversion. If you require the commonjs version of this library, 8 | stay on the 1.x version until you are ready to upgrade. 9 | * This library now requires Node 16. 10 | * Switch to built-in Node test runner and assertion library, and removed `nyc`, 11 | `mocha` and `chai`. 12 | 13 | 14 | 1.3.0 (2021-08-23) 15 | ------------------ 16 | 17 | * A faster algorithm for negative powers (@oliverlj). 18 | * Yearly dependency update 19 | * Typescript 4, new linting rules, switch to github actions. 20 | 21 | 22 | 1.2.0 (2020-08-01) 23 | ------------------ 24 | 25 | * Added `pow()` operation. 26 | 27 | 28 | 1.1.1 (2020-02-02) 29 | ------------------ 30 | 31 | * Update dependencies 32 | 33 | 34 | 1.1.0 (2019-06-12) 35 | ------------------ 36 | 37 | * `multiply()` and `divide()` can now accept other `Money` objects as 38 | arguments. 39 | 40 | 41 | 1.0.0 (2019-05-26) 42 | ------------------ 43 | 44 | * Added `abs()` function, to remove the sign from values. (@flaktack) 45 | * Added `sign()` function to find out if a number is postive, negative or zero 46 | (@flaktack). 47 | 48 | 49 | 0.8.2 (2019-04-03) 50 | ------------------ 51 | 52 | * Don't round numbers when used with `console.log()`. 53 | 54 | 55 | 0.8.1 (2019-03-21) 56 | ------------------ 57 | 58 | * Re-release of 0.8.0 with the correct build artifacts. 59 | * I've also updated `package.json` so we do a correct build before publish, so 60 | this issue won't happen again. 61 | 62 | 63 | 0.8.0 (2019-03-21) 64 | ------------------ 65 | 66 | * Increased the precision to 20 digits, up from 12. Someone had a need for more 67 | than 12 digits, and 20 seems like a reasonable new limit. Perhaps at one 68 | point this will be configurable but picking a good default seems like a sane 69 | choice right now. 70 | 71 | 72 | 0.7.1 (2019-03-19) 73 | ------------------ 74 | 75 | * Re-release: Stripped all development files from the npm package build. This 76 | makes the npm package a lot slimmer. 77 | 78 | 79 | 0.7.0 (2019-03-19) 80 | ------------------ 81 | 82 | * Added `isLesserThan`, `isGreaterThan`, `isEqual`, `isLesserThanOrEqual`, 83 | `isGreaterThanOrEqual` methods. 84 | 85 | 86 | 0.6.4 (2019-02-27) 87 | ------------------ 88 | 89 | * The last release didn't have all it's files correctly built. This version is 90 | a re-release that's properly built. 91 | 92 | 93 | 0.6.3 (2019-02-27) 94 | ------------------ 95 | 96 | * Regression from "0.6.2": Negative values were still incorrect for the same 97 | bug. 98 | 99 | 100 | 0.6.2 (2019-02-27) 101 | ------------------ 102 | 103 | * Fixed critical bug in `toFixed()` function. It can round `0.995` to `0.100` 104 | instead of `1`. This bug only appears when rounding decimals should increase 105 | the integer part. 106 | 107 | 108 | 0.6.1 (2019-02-25) 109 | ------------------ 110 | 111 | * Added `Round.HALF_TOWARDS_0`, `Round.TRUNCATE`. 112 | 113 | 114 | 0.6.0 (2019-02-23) 115 | ------------------ 116 | 117 | * It's not possible to specify the rounding method. The default is still 118 | `HALF_TO_EVEN` but a `HALF_AWAY_FROM_0` option has been added. 119 | 120 | 121 | 0.5.0 (2019-01-18) 122 | ------------------ 123 | 124 | * Added a `format()` function that simply returns the currency value as a 125 | string, with all insignificant 0's removed. 126 | 127 | 128 | 0.4.0 (2019-01-04) 129 | ------------------ 130 | 131 | * This library now adds a `toJSON()` function that has a default serialization 132 | for JSON files. Example: 1.5 USD will be JSON-stringified as `["1.5", 133 | "USD"]`. 134 | * The Money class is now the default export. 135 | 136 | 137 | 0.3.0 (2018-12-13) 138 | ------------------ 139 | 140 | * Support for `divide()`, `multiply()`, `compare()`. 141 | * Added an implementation of the `allocate()` function from Fowler's Enterprise 142 | Design Patterns. 143 | * Fixed parsing string numbers without a fractional part. 144 | * Added `toSource()` and `fromSource()` methods to easily get access to the 145 | underlying bigint. 146 | * `Money.value` is now private. 147 | * Nice v8 debugger output. Shows the currency + the symbol. 148 | 149 | 150 | 0.2.0 (2018-12-12) 151 | ------------------ 152 | 153 | * The rounding method everywhere is now 'Bankers rounding', also known as 154 | 'round half to even'. This is a more acceptable rounding for finanical 155 | purposes. 156 | * Moved some utilities into the `src/util.ts` function. 157 | * Fixed bugs in `toFixed()`. 158 | * Higher test coverage. 159 | 160 | 161 | 0.1.1 (2018-12-11) 162 | ------------------ 163 | 164 | * Fixed bugs. 165 | * More test coverage 166 | * Support for passing negative and floating point-as-string in constructor. 167 | * Readme with docs. 168 | 169 | 170 | 0.1.0 (2018-12-10) 171 | ------------------ 172 | 173 | * First working release. Support for basic arthimetic. 174 | * Temporarily dropped support for a webpack build until they support bigint. 175 | 176 | 177 | 0.0.1 (2018-12-06) 178 | ------------------ 179 | 180 | * First started working on this. 181 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bigint-money", 3 | "version": "2.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "bigint-money", 9 | "version": "2.0.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@types/node": "^20.12.7", 13 | "@typescript-eslint/eslint-plugin": "^7.7.0", 14 | "@typescript-eslint/parser": "^7.7.0", 15 | "eslint": "^8.57.0", 16 | "tsx": "^4.7.2", 17 | "typescript": "^5.4.5" 18 | } 19 | }, 20 | "node_modules/@aashutoshrathi/word-wrap": { 21 | "version": "1.2.6", 22 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", 23 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", 24 | "dev": true, 25 | "engines": { 26 | "node": ">=0.10.0" 27 | } 28 | }, 29 | "node_modules/@esbuild/aix-ppc64": { 30 | "version": "0.19.12", 31 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", 32 | "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", 33 | "cpu": [ 34 | "ppc64" 35 | ], 36 | "dev": true, 37 | "optional": true, 38 | "os": [ 39 | "aix" 40 | ], 41 | "engines": { 42 | "node": ">=12" 43 | } 44 | }, 45 | "node_modules/@esbuild/android-arm": { 46 | "version": "0.19.12", 47 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", 48 | "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", 49 | "cpu": [ 50 | "arm" 51 | ], 52 | "dev": true, 53 | "optional": true, 54 | "os": [ 55 | "android" 56 | ], 57 | "engines": { 58 | "node": ">=12" 59 | } 60 | }, 61 | "node_modules/@esbuild/android-arm64": { 62 | "version": "0.19.12", 63 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", 64 | "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", 65 | "cpu": [ 66 | "arm64" 67 | ], 68 | "dev": true, 69 | "optional": true, 70 | "os": [ 71 | "android" 72 | ], 73 | "engines": { 74 | "node": ">=12" 75 | } 76 | }, 77 | "node_modules/@esbuild/android-x64": { 78 | "version": "0.19.12", 79 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", 80 | "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", 81 | "cpu": [ 82 | "x64" 83 | ], 84 | "dev": true, 85 | "optional": true, 86 | "os": [ 87 | "android" 88 | ], 89 | "engines": { 90 | "node": ">=12" 91 | } 92 | }, 93 | "node_modules/@esbuild/darwin-arm64": { 94 | "version": "0.19.12", 95 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", 96 | "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", 97 | "cpu": [ 98 | "arm64" 99 | ], 100 | "dev": true, 101 | "optional": true, 102 | "os": [ 103 | "darwin" 104 | ], 105 | "engines": { 106 | "node": ">=12" 107 | } 108 | }, 109 | "node_modules/@esbuild/darwin-x64": { 110 | "version": "0.19.12", 111 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", 112 | "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", 113 | "cpu": [ 114 | "x64" 115 | ], 116 | "dev": true, 117 | "optional": true, 118 | "os": [ 119 | "darwin" 120 | ], 121 | "engines": { 122 | "node": ">=12" 123 | } 124 | }, 125 | "node_modules/@esbuild/freebsd-arm64": { 126 | "version": "0.19.12", 127 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", 128 | "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", 129 | "cpu": [ 130 | "arm64" 131 | ], 132 | "dev": true, 133 | "optional": true, 134 | "os": [ 135 | "freebsd" 136 | ], 137 | "engines": { 138 | "node": ">=12" 139 | } 140 | }, 141 | "node_modules/@esbuild/freebsd-x64": { 142 | "version": "0.19.12", 143 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", 144 | "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", 145 | "cpu": [ 146 | "x64" 147 | ], 148 | "dev": true, 149 | "optional": true, 150 | "os": [ 151 | "freebsd" 152 | ], 153 | "engines": { 154 | "node": ">=12" 155 | } 156 | }, 157 | "node_modules/@esbuild/linux-arm": { 158 | "version": "0.19.12", 159 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", 160 | "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", 161 | "cpu": [ 162 | "arm" 163 | ], 164 | "dev": true, 165 | "optional": true, 166 | "os": [ 167 | "linux" 168 | ], 169 | "engines": { 170 | "node": ">=12" 171 | } 172 | }, 173 | "node_modules/@esbuild/linux-arm64": { 174 | "version": "0.19.12", 175 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", 176 | "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", 177 | "cpu": [ 178 | "arm64" 179 | ], 180 | "dev": true, 181 | "optional": true, 182 | "os": [ 183 | "linux" 184 | ], 185 | "engines": { 186 | "node": ">=12" 187 | } 188 | }, 189 | "node_modules/@esbuild/linux-ia32": { 190 | "version": "0.19.12", 191 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", 192 | "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", 193 | "cpu": [ 194 | "ia32" 195 | ], 196 | "dev": true, 197 | "optional": true, 198 | "os": [ 199 | "linux" 200 | ], 201 | "engines": { 202 | "node": ">=12" 203 | } 204 | }, 205 | "node_modules/@esbuild/linux-loong64": { 206 | "version": "0.19.12", 207 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", 208 | "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", 209 | "cpu": [ 210 | "loong64" 211 | ], 212 | "dev": true, 213 | "optional": true, 214 | "os": [ 215 | "linux" 216 | ], 217 | "engines": { 218 | "node": ">=12" 219 | } 220 | }, 221 | "node_modules/@esbuild/linux-mips64el": { 222 | "version": "0.19.12", 223 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", 224 | "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", 225 | "cpu": [ 226 | "mips64el" 227 | ], 228 | "dev": true, 229 | "optional": true, 230 | "os": [ 231 | "linux" 232 | ], 233 | "engines": { 234 | "node": ">=12" 235 | } 236 | }, 237 | "node_modules/@esbuild/linux-ppc64": { 238 | "version": "0.19.12", 239 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", 240 | "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", 241 | "cpu": [ 242 | "ppc64" 243 | ], 244 | "dev": true, 245 | "optional": true, 246 | "os": [ 247 | "linux" 248 | ], 249 | "engines": { 250 | "node": ">=12" 251 | } 252 | }, 253 | "node_modules/@esbuild/linux-riscv64": { 254 | "version": "0.19.12", 255 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", 256 | "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", 257 | "cpu": [ 258 | "riscv64" 259 | ], 260 | "dev": true, 261 | "optional": true, 262 | "os": [ 263 | "linux" 264 | ], 265 | "engines": { 266 | "node": ">=12" 267 | } 268 | }, 269 | "node_modules/@esbuild/linux-s390x": { 270 | "version": "0.19.12", 271 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", 272 | "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", 273 | "cpu": [ 274 | "s390x" 275 | ], 276 | "dev": true, 277 | "optional": true, 278 | "os": [ 279 | "linux" 280 | ], 281 | "engines": { 282 | "node": ">=12" 283 | } 284 | }, 285 | "node_modules/@esbuild/linux-x64": { 286 | "version": "0.19.12", 287 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", 288 | "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", 289 | "cpu": [ 290 | "x64" 291 | ], 292 | "dev": true, 293 | "optional": true, 294 | "os": [ 295 | "linux" 296 | ], 297 | "engines": { 298 | "node": ">=12" 299 | } 300 | }, 301 | "node_modules/@esbuild/netbsd-x64": { 302 | "version": "0.19.12", 303 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", 304 | "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", 305 | "cpu": [ 306 | "x64" 307 | ], 308 | "dev": true, 309 | "optional": true, 310 | "os": [ 311 | "netbsd" 312 | ], 313 | "engines": { 314 | "node": ">=12" 315 | } 316 | }, 317 | "node_modules/@esbuild/openbsd-x64": { 318 | "version": "0.19.12", 319 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", 320 | "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", 321 | "cpu": [ 322 | "x64" 323 | ], 324 | "dev": true, 325 | "optional": true, 326 | "os": [ 327 | "openbsd" 328 | ], 329 | "engines": { 330 | "node": ">=12" 331 | } 332 | }, 333 | "node_modules/@esbuild/sunos-x64": { 334 | "version": "0.19.12", 335 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", 336 | "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", 337 | "cpu": [ 338 | "x64" 339 | ], 340 | "dev": true, 341 | "optional": true, 342 | "os": [ 343 | "sunos" 344 | ], 345 | "engines": { 346 | "node": ">=12" 347 | } 348 | }, 349 | "node_modules/@esbuild/win32-arm64": { 350 | "version": "0.19.12", 351 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", 352 | "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", 353 | "cpu": [ 354 | "arm64" 355 | ], 356 | "dev": true, 357 | "optional": true, 358 | "os": [ 359 | "win32" 360 | ], 361 | "engines": { 362 | "node": ">=12" 363 | } 364 | }, 365 | "node_modules/@esbuild/win32-ia32": { 366 | "version": "0.19.12", 367 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", 368 | "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", 369 | "cpu": [ 370 | "ia32" 371 | ], 372 | "dev": true, 373 | "optional": true, 374 | "os": [ 375 | "win32" 376 | ], 377 | "engines": { 378 | "node": ">=12" 379 | } 380 | }, 381 | "node_modules/@esbuild/win32-x64": { 382 | "version": "0.19.12", 383 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", 384 | "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", 385 | "cpu": [ 386 | "x64" 387 | ], 388 | "dev": true, 389 | "optional": true, 390 | "os": [ 391 | "win32" 392 | ], 393 | "engines": { 394 | "node": ">=12" 395 | } 396 | }, 397 | "node_modules/@eslint-community/eslint-utils": { 398 | "version": "4.4.0", 399 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 400 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 401 | "dev": true, 402 | "dependencies": { 403 | "eslint-visitor-keys": "^3.3.0" 404 | }, 405 | "engines": { 406 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 407 | }, 408 | "peerDependencies": { 409 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 410 | } 411 | }, 412 | "node_modules/@eslint-community/regexpp": { 413 | "version": "4.10.0", 414 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", 415 | "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", 416 | "dev": true, 417 | "engines": { 418 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 419 | } 420 | }, 421 | "node_modules/@eslint/eslintrc": { 422 | "version": "2.1.4", 423 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", 424 | "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", 425 | "dev": true, 426 | "dependencies": { 427 | "ajv": "^6.12.4", 428 | "debug": "^4.3.2", 429 | "espree": "^9.6.0", 430 | "globals": "^13.19.0", 431 | "ignore": "^5.2.0", 432 | "import-fresh": "^3.2.1", 433 | "js-yaml": "^4.1.0", 434 | "minimatch": "^3.1.2", 435 | "strip-json-comments": "^3.1.1" 436 | }, 437 | "engines": { 438 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 439 | }, 440 | "funding": { 441 | "url": "https://opencollective.com/eslint" 442 | } 443 | }, 444 | "node_modules/@eslint/eslintrc/node_modules/argparse": { 445 | "version": "2.0.1", 446 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 447 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 448 | "dev": true 449 | }, 450 | "node_modules/@eslint/eslintrc/node_modules/js-yaml": { 451 | "version": "4.1.0", 452 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 453 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 454 | "dev": true, 455 | "dependencies": { 456 | "argparse": "^2.0.1" 457 | }, 458 | "bin": { 459 | "js-yaml": "bin/js-yaml.js" 460 | } 461 | }, 462 | "node_modules/@eslint/js": { 463 | "version": "8.57.0", 464 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", 465 | "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", 466 | "dev": true, 467 | "engines": { 468 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 469 | } 470 | }, 471 | "node_modules/@humanwhocodes/config-array": { 472 | "version": "0.11.14", 473 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", 474 | "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", 475 | "dev": true, 476 | "dependencies": { 477 | "@humanwhocodes/object-schema": "^2.0.2", 478 | "debug": "^4.3.1", 479 | "minimatch": "^3.0.5" 480 | }, 481 | "engines": { 482 | "node": ">=10.10.0" 483 | } 484 | }, 485 | "node_modules/@humanwhocodes/module-importer": { 486 | "version": "1.0.1", 487 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 488 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 489 | "dev": true, 490 | "engines": { 491 | "node": ">=12.22" 492 | }, 493 | "funding": { 494 | "type": "github", 495 | "url": "https://github.com/sponsors/nzakas" 496 | } 497 | }, 498 | "node_modules/@humanwhocodes/object-schema": { 499 | "version": "2.0.3", 500 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", 501 | "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", 502 | "dev": true 503 | }, 504 | "node_modules/@nodelib/fs.scandir": { 505 | "version": "2.1.5", 506 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 507 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 508 | "dev": true, 509 | "dependencies": { 510 | "@nodelib/fs.stat": "2.0.5", 511 | "run-parallel": "^1.1.9" 512 | }, 513 | "engines": { 514 | "node": ">= 8" 515 | } 516 | }, 517 | "node_modules/@nodelib/fs.stat": { 518 | "version": "2.0.5", 519 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 520 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 521 | "dev": true, 522 | "engines": { 523 | "node": ">= 8" 524 | } 525 | }, 526 | "node_modules/@nodelib/fs.walk": { 527 | "version": "1.2.8", 528 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 529 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 530 | "dev": true, 531 | "dependencies": { 532 | "@nodelib/fs.scandir": "2.1.5", 533 | "fastq": "^1.6.0" 534 | }, 535 | "engines": { 536 | "node": ">= 8" 537 | } 538 | }, 539 | "node_modules/@types/json-schema": { 540 | "version": "7.0.15", 541 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 542 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 543 | "dev": true 544 | }, 545 | "node_modules/@types/node": { 546 | "version": "20.12.7", 547 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", 548 | "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", 549 | "dev": true, 550 | "dependencies": { 551 | "undici-types": "~5.26.4" 552 | } 553 | }, 554 | "node_modules/@types/semver": { 555 | "version": "7.5.8", 556 | "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", 557 | "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", 558 | "dev": true 559 | }, 560 | "node_modules/@typescript-eslint/eslint-plugin": { 561 | "version": "7.7.0", 562 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", 563 | "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", 564 | "dev": true, 565 | "dependencies": { 566 | "@eslint-community/regexpp": "^4.10.0", 567 | "@typescript-eslint/scope-manager": "7.7.0", 568 | "@typescript-eslint/type-utils": "7.7.0", 569 | "@typescript-eslint/utils": "7.7.0", 570 | "@typescript-eslint/visitor-keys": "7.7.0", 571 | "debug": "^4.3.4", 572 | "graphemer": "^1.4.0", 573 | "ignore": "^5.3.1", 574 | "natural-compare": "^1.4.0", 575 | "semver": "^7.6.0", 576 | "ts-api-utils": "^1.3.0" 577 | }, 578 | "engines": { 579 | "node": "^18.18.0 || >=20.0.0" 580 | }, 581 | "funding": { 582 | "type": "opencollective", 583 | "url": "https://opencollective.com/typescript-eslint" 584 | }, 585 | "peerDependencies": { 586 | "@typescript-eslint/parser": "^7.0.0", 587 | "eslint": "^8.56.0" 588 | }, 589 | "peerDependenciesMeta": { 590 | "typescript": { 591 | "optional": true 592 | } 593 | } 594 | }, 595 | "node_modules/@typescript-eslint/parser": { 596 | "version": "7.7.0", 597 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", 598 | "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", 599 | "dev": true, 600 | "dependencies": { 601 | "@typescript-eslint/scope-manager": "7.7.0", 602 | "@typescript-eslint/types": "7.7.0", 603 | "@typescript-eslint/typescript-estree": "7.7.0", 604 | "@typescript-eslint/visitor-keys": "7.7.0", 605 | "debug": "^4.3.4" 606 | }, 607 | "engines": { 608 | "node": "^18.18.0 || >=20.0.0" 609 | }, 610 | "funding": { 611 | "type": "opencollective", 612 | "url": "https://opencollective.com/typescript-eslint" 613 | }, 614 | "peerDependencies": { 615 | "eslint": "^8.56.0" 616 | }, 617 | "peerDependenciesMeta": { 618 | "typescript": { 619 | "optional": true 620 | } 621 | } 622 | }, 623 | "node_modules/@typescript-eslint/scope-manager": { 624 | "version": "7.7.0", 625 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", 626 | "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", 627 | "dev": true, 628 | "dependencies": { 629 | "@typescript-eslint/types": "7.7.0", 630 | "@typescript-eslint/visitor-keys": "7.7.0" 631 | }, 632 | "engines": { 633 | "node": "^18.18.0 || >=20.0.0" 634 | }, 635 | "funding": { 636 | "type": "opencollective", 637 | "url": "https://opencollective.com/typescript-eslint" 638 | } 639 | }, 640 | "node_modules/@typescript-eslint/type-utils": { 641 | "version": "7.7.0", 642 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", 643 | "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", 644 | "dev": true, 645 | "dependencies": { 646 | "@typescript-eslint/typescript-estree": "7.7.0", 647 | "@typescript-eslint/utils": "7.7.0", 648 | "debug": "^4.3.4", 649 | "ts-api-utils": "^1.3.0" 650 | }, 651 | "engines": { 652 | "node": "^18.18.0 || >=20.0.0" 653 | }, 654 | "funding": { 655 | "type": "opencollective", 656 | "url": "https://opencollective.com/typescript-eslint" 657 | }, 658 | "peerDependencies": { 659 | "eslint": "^8.56.0" 660 | }, 661 | "peerDependenciesMeta": { 662 | "typescript": { 663 | "optional": true 664 | } 665 | } 666 | }, 667 | "node_modules/@typescript-eslint/types": { 668 | "version": "7.7.0", 669 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", 670 | "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", 671 | "dev": true, 672 | "engines": { 673 | "node": "^18.18.0 || >=20.0.0" 674 | }, 675 | "funding": { 676 | "type": "opencollective", 677 | "url": "https://opencollective.com/typescript-eslint" 678 | } 679 | }, 680 | "node_modules/@typescript-eslint/typescript-estree": { 681 | "version": "7.7.0", 682 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", 683 | "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", 684 | "dev": true, 685 | "dependencies": { 686 | "@typescript-eslint/types": "7.7.0", 687 | "@typescript-eslint/visitor-keys": "7.7.0", 688 | "debug": "^4.3.4", 689 | "globby": "^11.1.0", 690 | "is-glob": "^4.0.3", 691 | "minimatch": "^9.0.4", 692 | "semver": "^7.6.0", 693 | "ts-api-utils": "^1.3.0" 694 | }, 695 | "engines": { 696 | "node": "^18.18.0 || >=20.0.0" 697 | }, 698 | "funding": { 699 | "type": "opencollective", 700 | "url": "https://opencollective.com/typescript-eslint" 701 | }, 702 | "peerDependenciesMeta": { 703 | "typescript": { 704 | "optional": true 705 | } 706 | } 707 | }, 708 | "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 709 | "version": "2.0.1", 710 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 711 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 712 | "dev": true, 713 | "dependencies": { 714 | "balanced-match": "^1.0.0" 715 | } 716 | }, 717 | "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 718 | "version": "9.0.4", 719 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", 720 | "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", 721 | "dev": true, 722 | "dependencies": { 723 | "brace-expansion": "^2.0.1" 724 | }, 725 | "engines": { 726 | "node": ">=16 || 14 >=14.17" 727 | }, 728 | "funding": { 729 | "url": "https://github.com/sponsors/isaacs" 730 | } 731 | }, 732 | "node_modules/@typescript-eslint/utils": { 733 | "version": "7.7.0", 734 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", 735 | "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", 736 | "dev": true, 737 | "dependencies": { 738 | "@eslint-community/eslint-utils": "^4.4.0", 739 | "@types/json-schema": "^7.0.15", 740 | "@types/semver": "^7.5.8", 741 | "@typescript-eslint/scope-manager": "7.7.0", 742 | "@typescript-eslint/types": "7.7.0", 743 | "@typescript-eslint/typescript-estree": "7.7.0", 744 | "semver": "^7.6.0" 745 | }, 746 | "engines": { 747 | "node": "^18.18.0 || >=20.0.0" 748 | }, 749 | "funding": { 750 | "type": "opencollective", 751 | "url": "https://opencollective.com/typescript-eslint" 752 | }, 753 | "peerDependencies": { 754 | "eslint": "^8.56.0" 755 | } 756 | }, 757 | "node_modules/@typescript-eslint/visitor-keys": { 758 | "version": "7.7.0", 759 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", 760 | "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", 761 | "dev": true, 762 | "dependencies": { 763 | "@typescript-eslint/types": "7.7.0", 764 | "eslint-visitor-keys": "^3.4.3" 765 | }, 766 | "engines": { 767 | "node": "^18.18.0 || >=20.0.0" 768 | }, 769 | "funding": { 770 | "type": "opencollective", 771 | "url": "https://opencollective.com/typescript-eslint" 772 | } 773 | }, 774 | "node_modules/@ungap/structured-clone": { 775 | "version": "1.2.0", 776 | "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", 777 | "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", 778 | "dev": true 779 | }, 780 | "node_modules/acorn": { 781 | "version": "8.11.3", 782 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 783 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 784 | "dev": true, 785 | "bin": { 786 | "acorn": "bin/acorn" 787 | }, 788 | "engines": { 789 | "node": ">=0.4.0" 790 | } 791 | }, 792 | "node_modules/acorn-jsx": { 793 | "version": "5.3.2", 794 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 795 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 796 | "dev": true, 797 | "peerDependencies": { 798 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 799 | } 800 | }, 801 | "node_modules/ajv": { 802 | "version": "6.12.6", 803 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 804 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 805 | "dev": true, 806 | "dependencies": { 807 | "fast-deep-equal": "^3.1.1", 808 | "fast-json-stable-stringify": "^2.0.0", 809 | "json-schema-traverse": "^0.4.1", 810 | "uri-js": "^4.2.2" 811 | }, 812 | "funding": { 813 | "type": "github", 814 | "url": "https://github.com/sponsors/epoberezkin" 815 | } 816 | }, 817 | "node_modules/ansi-regex": { 818 | "version": "5.0.1", 819 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 820 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 821 | "dev": true, 822 | "engines": { 823 | "node": ">=8" 824 | } 825 | }, 826 | "node_modules/ansi-styles": { 827 | "version": "4.3.0", 828 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 829 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 830 | "dev": true, 831 | "dependencies": { 832 | "color-convert": "^2.0.1" 833 | }, 834 | "engines": { 835 | "node": ">=8" 836 | }, 837 | "funding": { 838 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 839 | } 840 | }, 841 | "node_modules/array-union": { 842 | "version": "2.1.0", 843 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 844 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 845 | "dev": true, 846 | "engines": { 847 | "node": ">=8" 848 | } 849 | }, 850 | "node_modules/balanced-match": { 851 | "version": "1.0.2", 852 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 853 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 854 | "dev": true 855 | }, 856 | "node_modules/brace-expansion": { 857 | "version": "1.1.11", 858 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 859 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 860 | "dev": true, 861 | "dependencies": { 862 | "balanced-match": "^1.0.0", 863 | "concat-map": "0.0.1" 864 | } 865 | }, 866 | "node_modules/braces": { 867 | "version": "3.0.2", 868 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 869 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 870 | "dev": true, 871 | "dependencies": { 872 | "fill-range": "^7.0.1" 873 | }, 874 | "engines": { 875 | "node": ">=8" 876 | } 877 | }, 878 | "node_modules/callsites": { 879 | "version": "3.1.0", 880 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 881 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 882 | "dev": true, 883 | "engines": { 884 | "node": ">=6" 885 | } 886 | }, 887 | "node_modules/chalk": { 888 | "version": "4.1.2", 889 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 890 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 891 | "dev": true, 892 | "dependencies": { 893 | "ansi-styles": "^4.1.0", 894 | "supports-color": "^7.1.0" 895 | }, 896 | "engines": { 897 | "node": ">=10" 898 | }, 899 | "funding": { 900 | "url": "https://github.com/chalk/chalk?sponsor=1" 901 | } 902 | }, 903 | "node_modules/color-convert": { 904 | "version": "2.0.1", 905 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 906 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 907 | "dev": true, 908 | "dependencies": { 909 | "color-name": "~1.1.4" 910 | }, 911 | "engines": { 912 | "node": ">=7.0.0" 913 | } 914 | }, 915 | "node_modules/color-name": { 916 | "version": "1.1.4", 917 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 918 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 919 | "dev": true 920 | }, 921 | "node_modules/concat-map": { 922 | "version": "0.0.1", 923 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 924 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 925 | "dev": true 926 | }, 927 | "node_modules/cross-spawn": { 928 | "version": "7.0.3", 929 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 930 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 931 | "dev": true, 932 | "dependencies": { 933 | "path-key": "^3.1.0", 934 | "shebang-command": "^2.0.0", 935 | "which": "^2.0.1" 936 | }, 937 | "engines": { 938 | "node": ">= 8" 939 | } 940 | }, 941 | "node_modules/debug": { 942 | "version": "4.3.4", 943 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 944 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 945 | "dev": true, 946 | "dependencies": { 947 | "ms": "2.1.2" 948 | }, 949 | "engines": { 950 | "node": ">=6.0" 951 | }, 952 | "peerDependenciesMeta": { 953 | "supports-color": { 954 | "optional": true 955 | } 956 | } 957 | }, 958 | "node_modules/deep-is": { 959 | "version": "0.1.4", 960 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 961 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 962 | "dev": true 963 | }, 964 | "node_modules/dir-glob": { 965 | "version": "3.0.1", 966 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 967 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 968 | "dev": true, 969 | "dependencies": { 970 | "path-type": "^4.0.0" 971 | }, 972 | "engines": { 973 | "node": ">=8" 974 | } 975 | }, 976 | "node_modules/doctrine": { 977 | "version": "3.0.0", 978 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 979 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 980 | "dev": true, 981 | "dependencies": { 982 | "esutils": "^2.0.2" 983 | }, 984 | "engines": { 985 | "node": ">=6.0.0" 986 | } 987 | }, 988 | "node_modules/esbuild": { 989 | "version": "0.19.12", 990 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", 991 | "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", 992 | "dev": true, 993 | "hasInstallScript": true, 994 | "bin": { 995 | "esbuild": "bin/esbuild" 996 | }, 997 | "engines": { 998 | "node": ">=12" 999 | }, 1000 | "optionalDependencies": { 1001 | "@esbuild/aix-ppc64": "0.19.12", 1002 | "@esbuild/android-arm": "0.19.12", 1003 | "@esbuild/android-arm64": "0.19.12", 1004 | "@esbuild/android-x64": "0.19.12", 1005 | "@esbuild/darwin-arm64": "0.19.12", 1006 | "@esbuild/darwin-x64": "0.19.12", 1007 | "@esbuild/freebsd-arm64": "0.19.12", 1008 | "@esbuild/freebsd-x64": "0.19.12", 1009 | "@esbuild/linux-arm": "0.19.12", 1010 | "@esbuild/linux-arm64": "0.19.12", 1011 | "@esbuild/linux-ia32": "0.19.12", 1012 | "@esbuild/linux-loong64": "0.19.12", 1013 | "@esbuild/linux-mips64el": "0.19.12", 1014 | "@esbuild/linux-ppc64": "0.19.12", 1015 | "@esbuild/linux-riscv64": "0.19.12", 1016 | "@esbuild/linux-s390x": "0.19.12", 1017 | "@esbuild/linux-x64": "0.19.12", 1018 | "@esbuild/netbsd-x64": "0.19.12", 1019 | "@esbuild/openbsd-x64": "0.19.12", 1020 | "@esbuild/sunos-x64": "0.19.12", 1021 | "@esbuild/win32-arm64": "0.19.12", 1022 | "@esbuild/win32-ia32": "0.19.12", 1023 | "@esbuild/win32-x64": "0.19.12" 1024 | } 1025 | }, 1026 | "node_modules/escape-string-regexp": { 1027 | "version": "4.0.0", 1028 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1029 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1030 | "dev": true, 1031 | "engines": { 1032 | "node": ">=10" 1033 | }, 1034 | "funding": { 1035 | "url": "https://github.com/sponsors/sindresorhus" 1036 | } 1037 | }, 1038 | "node_modules/eslint": { 1039 | "version": "8.57.0", 1040 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", 1041 | "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", 1042 | "dev": true, 1043 | "dependencies": { 1044 | "@eslint-community/eslint-utils": "^4.2.0", 1045 | "@eslint-community/regexpp": "^4.6.1", 1046 | "@eslint/eslintrc": "^2.1.4", 1047 | "@eslint/js": "8.57.0", 1048 | "@humanwhocodes/config-array": "^0.11.14", 1049 | "@humanwhocodes/module-importer": "^1.0.1", 1050 | "@nodelib/fs.walk": "^1.2.8", 1051 | "@ungap/structured-clone": "^1.2.0", 1052 | "ajv": "^6.12.4", 1053 | "chalk": "^4.0.0", 1054 | "cross-spawn": "^7.0.2", 1055 | "debug": "^4.3.2", 1056 | "doctrine": "^3.0.0", 1057 | "escape-string-regexp": "^4.0.0", 1058 | "eslint-scope": "^7.2.2", 1059 | "eslint-visitor-keys": "^3.4.3", 1060 | "espree": "^9.6.1", 1061 | "esquery": "^1.4.2", 1062 | "esutils": "^2.0.2", 1063 | "fast-deep-equal": "^3.1.3", 1064 | "file-entry-cache": "^6.0.1", 1065 | "find-up": "^5.0.0", 1066 | "glob-parent": "^6.0.2", 1067 | "globals": "^13.19.0", 1068 | "graphemer": "^1.4.0", 1069 | "ignore": "^5.2.0", 1070 | "imurmurhash": "^0.1.4", 1071 | "is-glob": "^4.0.0", 1072 | "is-path-inside": "^3.0.3", 1073 | "js-yaml": "^4.1.0", 1074 | "json-stable-stringify-without-jsonify": "^1.0.1", 1075 | "levn": "^0.4.1", 1076 | "lodash.merge": "^4.6.2", 1077 | "minimatch": "^3.1.2", 1078 | "natural-compare": "^1.4.0", 1079 | "optionator": "^0.9.3", 1080 | "strip-ansi": "^6.0.1", 1081 | "text-table": "^0.2.0" 1082 | }, 1083 | "bin": { 1084 | "eslint": "bin/eslint.js" 1085 | }, 1086 | "engines": { 1087 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1088 | }, 1089 | "funding": { 1090 | "url": "https://opencollective.com/eslint" 1091 | } 1092 | }, 1093 | "node_modules/eslint-scope": { 1094 | "version": "7.2.2", 1095 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", 1096 | "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", 1097 | "dev": true, 1098 | "dependencies": { 1099 | "esrecurse": "^4.3.0", 1100 | "estraverse": "^5.2.0" 1101 | }, 1102 | "engines": { 1103 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1104 | }, 1105 | "funding": { 1106 | "url": "https://opencollective.com/eslint" 1107 | } 1108 | }, 1109 | "node_modules/eslint-visitor-keys": { 1110 | "version": "3.4.3", 1111 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 1112 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 1113 | "dev": true, 1114 | "engines": { 1115 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1116 | }, 1117 | "funding": { 1118 | "url": "https://opencollective.com/eslint" 1119 | } 1120 | }, 1121 | "node_modules/eslint/node_modules/argparse": { 1122 | "version": "2.0.1", 1123 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1124 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1125 | "dev": true 1126 | }, 1127 | "node_modules/eslint/node_modules/glob-parent": { 1128 | "version": "6.0.2", 1129 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1130 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1131 | "dev": true, 1132 | "dependencies": { 1133 | "is-glob": "^4.0.3" 1134 | }, 1135 | "engines": { 1136 | "node": ">=10.13.0" 1137 | } 1138 | }, 1139 | "node_modules/eslint/node_modules/js-yaml": { 1140 | "version": "4.1.0", 1141 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1142 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1143 | "dev": true, 1144 | "dependencies": { 1145 | "argparse": "^2.0.1" 1146 | }, 1147 | "bin": { 1148 | "js-yaml": "bin/js-yaml.js" 1149 | } 1150 | }, 1151 | "node_modules/espree": { 1152 | "version": "9.6.1", 1153 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", 1154 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", 1155 | "dev": true, 1156 | "dependencies": { 1157 | "acorn": "^8.9.0", 1158 | "acorn-jsx": "^5.3.2", 1159 | "eslint-visitor-keys": "^3.4.1" 1160 | }, 1161 | "engines": { 1162 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1163 | }, 1164 | "funding": { 1165 | "url": "https://opencollective.com/eslint" 1166 | } 1167 | }, 1168 | "node_modules/esquery": { 1169 | "version": "1.5.0", 1170 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 1171 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 1172 | "dev": true, 1173 | "dependencies": { 1174 | "estraverse": "^5.1.0" 1175 | }, 1176 | "engines": { 1177 | "node": ">=0.10" 1178 | } 1179 | }, 1180 | "node_modules/esrecurse": { 1181 | "version": "4.3.0", 1182 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1183 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1184 | "dev": true, 1185 | "dependencies": { 1186 | "estraverse": "^5.2.0" 1187 | }, 1188 | "engines": { 1189 | "node": ">=4.0" 1190 | } 1191 | }, 1192 | "node_modules/estraverse": { 1193 | "version": "5.3.0", 1194 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1195 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1196 | "dev": true, 1197 | "engines": { 1198 | "node": ">=4.0" 1199 | } 1200 | }, 1201 | "node_modules/esutils": { 1202 | "version": "2.0.3", 1203 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1204 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1205 | "dev": true, 1206 | "engines": { 1207 | "node": ">=0.10.0" 1208 | } 1209 | }, 1210 | "node_modules/fast-deep-equal": { 1211 | "version": "3.1.3", 1212 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1213 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1214 | "dev": true 1215 | }, 1216 | "node_modules/fast-glob": { 1217 | "version": "3.3.2", 1218 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 1219 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 1220 | "dev": true, 1221 | "dependencies": { 1222 | "@nodelib/fs.stat": "^2.0.2", 1223 | "@nodelib/fs.walk": "^1.2.3", 1224 | "glob-parent": "^5.1.2", 1225 | "merge2": "^1.3.0", 1226 | "micromatch": "^4.0.4" 1227 | }, 1228 | "engines": { 1229 | "node": ">=8.6.0" 1230 | } 1231 | }, 1232 | "node_modules/fast-json-stable-stringify": { 1233 | "version": "2.1.0", 1234 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1235 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1236 | "dev": true 1237 | }, 1238 | "node_modules/fast-levenshtein": { 1239 | "version": "2.0.6", 1240 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1241 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1242 | "dev": true 1243 | }, 1244 | "node_modules/fastq": { 1245 | "version": "1.17.1", 1246 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 1247 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 1248 | "dev": true, 1249 | "dependencies": { 1250 | "reusify": "^1.0.4" 1251 | } 1252 | }, 1253 | "node_modules/file-entry-cache": { 1254 | "version": "6.0.1", 1255 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 1256 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 1257 | "dev": true, 1258 | "dependencies": { 1259 | "flat-cache": "^3.0.4" 1260 | }, 1261 | "engines": { 1262 | "node": "^10.12.0 || >=12.0.0" 1263 | } 1264 | }, 1265 | "node_modules/fill-range": { 1266 | "version": "7.0.1", 1267 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1268 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1269 | "dev": true, 1270 | "dependencies": { 1271 | "to-regex-range": "^5.0.1" 1272 | }, 1273 | "engines": { 1274 | "node": ">=8" 1275 | } 1276 | }, 1277 | "node_modules/find-up": { 1278 | "version": "5.0.0", 1279 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1280 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1281 | "dev": true, 1282 | "dependencies": { 1283 | "locate-path": "^6.0.0", 1284 | "path-exists": "^4.0.0" 1285 | }, 1286 | "engines": { 1287 | "node": ">=10" 1288 | }, 1289 | "funding": { 1290 | "url": "https://github.com/sponsors/sindresorhus" 1291 | } 1292 | }, 1293 | "node_modules/flat-cache": { 1294 | "version": "3.2.0", 1295 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", 1296 | "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", 1297 | "dev": true, 1298 | "dependencies": { 1299 | "flatted": "^3.2.9", 1300 | "keyv": "^4.5.3", 1301 | "rimraf": "^3.0.2" 1302 | }, 1303 | "engines": { 1304 | "node": "^10.12.0 || >=12.0.0" 1305 | } 1306 | }, 1307 | "node_modules/flatted": { 1308 | "version": "3.3.1", 1309 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", 1310 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", 1311 | "dev": true 1312 | }, 1313 | "node_modules/fs.realpath": { 1314 | "version": "1.0.0", 1315 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1316 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1317 | "dev": true 1318 | }, 1319 | "node_modules/fsevents": { 1320 | "version": "2.3.3", 1321 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1322 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1323 | "dev": true, 1324 | "hasInstallScript": true, 1325 | "optional": true, 1326 | "os": [ 1327 | "darwin" 1328 | ], 1329 | "engines": { 1330 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1331 | } 1332 | }, 1333 | "node_modules/get-tsconfig": { 1334 | "version": "4.7.3", 1335 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", 1336 | "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", 1337 | "dev": true, 1338 | "dependencies": { 1339 | "resolve-pkg-maps": "^1.0.0" 1340 | }, 1341 | "funding": { 1342 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" 1343 | } 1344 | }, 1345 | "node_modules/glob": { 1346 | "version": "7.2.0", 1347 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 1348 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 1349 | "dev": true, 1350 | "dependencies": { 1351 | "fs.realpath": "^1.0.0", 1352 | "inflight": "^1.0.4", 1353 | "inherits": "2", 1354 | "minimatch": "^3.0.4", 1355 | "once": "^1.3.0", 1356 | "path-is-absolute": "^1.0.0" 1357 | }, 1358 | "engines": { 1359 | "node": "*" 1360 | }, 1361 | "funding": { 1362 | "url": "https://github.com/sponsors/isaacs" 1363 | } 1364 | }, 1365 | "node_modules/glob-parent": { 1366 | "version": "5.1.2", 1367 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1368 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1369 | "dev": true, 1370 | "dependencies": { 1371 | "is-glob": "^4.0.1" 1372 | }, 1373 | "engines": { 1374 | "node": ">= 6" 1375 | } 1376 | }, 1377 | "node_modules/globals": { 1378 | "version": "13.24.0", 1379 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", 1380 | "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", 1381 | "dev": true, 1382 | "dependencies": { 1383 | "type-fest": "^0.20.2" 1384 | }, 1385 | "engines": { 1386 | "node": ">=8" 1387 | }, 1388 | "funding": { 1389 | "url": "https://github.com/sponsors/sindresorhus" 1390 | } 1391 | }, 1392 | "node_modules/globby": { 1393 | "version": "11.1.0", 1394 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 1395 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 1396 | "dev": true, 1397 | "dependencies": { 1398 | "array-union": "^2.1.0", 1399 | "dir-glob": "^3.0.1", 1400 | "fast-glob": "^3.2.9", 1401 | "ignore": "^5.2.0", 1402 | "merge2": "^1.4.1", 1403 | "slash": "^3.0.0" 1404 | }, 1405 | "engines": { 1406 | "node": ">=10" 1407 | }, 1408 | "funding": { 1409 | "url": "https://github.com/sponsors/sindresorhus" 1410 | } 1411 | }, 1412 | "node_modules/graphemer": { 1413 | "version": "1.4.0", 1414 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 1415 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 1416 | "dev": true 1417 | }, 1418 | "node_modules/has-flag": { 1419 | "version": "4.0.0", 1420 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1421 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1422 | "dev": true, 1423 | "engines": { 1424 | "node": ">=8" 1425 | } 1426 | }, 1427 | "node_modules/ignore": { 1428 | "version": "5.3.1", 1429 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", 1430 | "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", 1431 | "dev": true, 1432 | "engines": { 1433 | "node": ">= 4" 1434 | } 1435 | }, 1436 | "node_modules/import-fresh": { 1437 | "version": "3.3.0", 1438 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 1439 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 1440 | "dev": true, 1441 | "dependencies": { 1442 | "parent-module": "^1.0.0", 1443 | "resolve-from": "^4.0.0" 1444 | }, 1445 | "engines": { 1446 | "node": ">=6" 1447 | }, 1448 | "funding": { 1449 | "url": "https://github.com/sponsors/sindresorhus" 1450 | } 1451 | }, 1452 | "node_modules/imurmurhash": { 1453 | "version": "0.1.4", 1454 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1455 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1456 | "dev": true, 1457 | "engines": { 1458 | "node": ">=0.8.19" 1459 | } 1460 | }, 1461 | "node_modules/inflight": { 1462 | "version": "1.0.6", 1463 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1464 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1465 | "dev": true, 1466 | "dependencies": { 1467 | "once": "^1.3.0", 1468 | "wrappy": "1" 1469 | } 1470 | }, 1471 | "node_modules/inherits": { 1472 | "version": "2.0.4", 1473 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1474 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1475 | "dev": true 1476 | }, 1477 | "node_modules/is-extglob": { 1478 | "version": "2.1.1", 1479 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1480 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1481 | "dev": true, 1482 | "engines": { 1483 | "node": ">=0.10.0" 1484 | } 1485 | }, 1486 | "node_modules/is-glob": { 1487 | "version": "4.0.3", 1488 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1489 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1490 | "dev": true, 1491 | "dependencies": { 1492 | "is-extglob": "^2.1.1" 1493 | }, 1494 | "engines": { 1495 | "node": ">=0.10.0" 1496 | } 1497 | }, 1498 | "node_modules/is-number": { 1499 | "version": "7.0.0", 1500 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1501 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1502 | "dev": true, 1503 | "engines": { 1504 | "node": ">=0.12.0" 1505 | } 1506 | }, 1507 | "node_modules/is-path-inside": { 1508 | "version": "3.0.3", 1509 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 1510 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 1511 | "dev": true, 1512 | "engines": { 1513 | "node": ">=8" 1514 | } 1515 | }, 1516 | "node_modules/isexe": { 1517 | "version": "2.0.0", 1518 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1519 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1520 | "dev": true 1521 | }, 1522 | "node_modules/json-buffer": { 1523 | "version": "3.0.1", 1524 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 1525 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 1526 | "dev": true 1527 | }, 1528 | "node_modules/json-schema-traverse": { 1529 | "version": "0.4.1", 1530 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1531 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1532 | "dev": true 1533 | }, 1534 | "node_modules/json-stable-stringify-without-jsonify": { 1535 | "version": "1.0.1", 1536 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1537 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 1538 | "dev": true 1539 | }, 1540 | "node_modules/keyv": { 1541 | "version": "4.5.4", 1542 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 1543 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 1544 | "dev": true, 1545 | "dependencies": { 1546 | "json-buffer": "3.0.1" 1547 | } 1548 | }, 1549 | "node_modules/levn": { 1550 | "version": "0.4.1", 1551 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1552 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1553 | "dev": true, 1554 | "dependencies": { 1555 | "prelude-ls": "^1.2.1", 1556 | "type-check": "~0.4.0" 1557 | }, 1558 | "engines": { 1559 | "node": ">= 0.8.0" 1560 | } 1561 | }, 1562 | "node_modules/locate-path": { 1563 | "version": "6.0.0", 1564 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1565 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1566 | "dev": true, 1567 | "dependencies": { 1568 | "p-locate": "^5.0.0" 1569 | }, 1570 | "engines": { 1571 | "node": ">=10" 1572 | }, 1573 | "funding": { 1574 | "url": "https://github.com/sponsors/sindresorhus" 1575 | } 1576 | }, 1577 | "node_modules/lodash.merge": { 1578 | "version": "4.6.2", 1579 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1580 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1581 | "dev": true 1582 | }, 1583 | "node_modules/merge2": { 1584 | "version": "1.4.1", 1585 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1586 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1587 | "dev": true, 1588 | "engines": { 1589 | "node": ">= 8" 1590 | } 1591 | }, 1592 | "node_modules/micromatch": { 1593 | "version": "4.0.5", 1594 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1595 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1596 | "dev": true, 1597 | "dependencies": { 1598 | "braces": "^3.0.2", 1599 | "picomatch": "^2.3.1" 1600 | }, 1601 | "engines": { 1602 | "node": ">=8.6" 1603 | } 1604 | }, 1605 | "node_modules/minimatch": { 1606 | "version": "3.1.2", 1607 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1608 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1609 | "dev": true, 1610 | "dependencies": { 1611 | "brace-expansion": "^1.1.7" 1612 | }, 1613 | "engines": { 1614 | "node": "*" 1615 | } 1616 | }, 1617 | "node_modules/ms": { 1618 | "version": "2.1.2", 1619 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1620 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1621 | "dev": true 1622 | }, 1623 | "node_modules/natural-compare": { 1624 | "version": "1.4.0", 1625 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1626 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1627 | "dev": true 1628 | }, 1629 | "node_modules/once": { 1630 | "version": "1.4.0", 1631 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1632 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1633 | "dev": true, 1634 | "dependencies": { 1635 | "wrappy": "1" 1636 | } 1637 | }, 1638 | "node_modules/optionator": { 1639 | "version": "0.9.3", 1640 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", 1641 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", 1642 | "dev": true, 1643 | "dependencies": { 1644 | "@aashutoshrathi/word-wrap": "^1.2.3", 1645 | "deep-is": "^0.1.3", 1646 | "fast-levenshtein": "^2.0.6", 1647 | "levn": "^0.4.1", 1648 | "prelude-ls": "^1.2.1", 1649 | "type-check": "^0.4.0" 1650 | }, 1651 | "engines": { 1652 | "node": ">= 0.8.0" 1653 | } 1654 | }, 1655 | "node_modules/p-limit": { 1656 | "version": "3.1.0", 1657 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1658 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1659 | "dev": true, 1660 | "dependencies": { 1661 | "yocto-queue": "^0.1.0" 1662 | }, 1663 | "engines": { 1664 | "node": ">=10" 1665 | }, 1666 | "funding": { 1667 | "url": "https://github.com/sponsors/sindresorhus" 1668 | } 1669 | }, 1670 | "node_modules/p-locate": { 1671 | "version": "5.0.0", 1672 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1673 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1674 | "dev": true, 1675 | "dependencies": { 1676 | "p-limit": "^3.0.2" 1677 | }, 1678 | "engines": { 1679 | "node": ">=10" 1680 | }, 1681 | "funding": { 1682 | "url": "https://github.com/sponsors/sindresorhus" 1683 | } 1684 | }, 1685 | "node_modules/parent-module": { 1686 | "version": "1.0.1", 1687 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1688 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1689 | "dev": true, 1690 | "dependencies": { 1691 | "callsites": "^3.0.0" 1692 | }, 1693 | "engines": { 1694 | "node": ">=6" 1695 | } 1696 | }, 1697 | "node_modules/path-exists": { 1698 | "version": "4.0.0", 1699 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1700 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1701 | "dev": true, 1702 | "engines": { 1703 | "node": ">=8" 1704 | } 1705 | }, 1706 | "node_modules/path-is-absolute": { 1707 | "version": "1.0.1", 1708 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1709 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1710 | "dev": true, 1711 | "engines": { 1712 | "node": ">=0.10.0" 1713 | } 1714 | }, 1715 | "node_modules/path-key": { 1716 | "version": "3.1.1", 1717 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1718 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1719 | "dev": true, 1720 | "engines": { 1721 | "node": ">=8" 1722 | } 1723 | }, 1724 | "node_modules/path-type": { 1725 | "version": "4.0.0", 1726 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1727 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1728 | "dev": true, 1729 | "engines": { 1730 | "node": ">=8" 1731 | } 1732 | }, 1733 | "node_modules/picomatch": { 1734 | "version": "2.3.1", 1735 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1736 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1737 | "dev": true, 1738 | "engines": { 1739 | "node": ">=8.6" 1740 | }, 1741 | "funding": { 1742 | "url": "https://github.com/sponsors/jonschlinkert" 1743 | } 1744 | }, 1745 | "node_modules/prelude-ls": { 1746 | "version": "1.2.1", 1747 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1748 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1749 | "dev": true, 1750 | "engines": { 1751 | "node": ">= 0.8.0" 1752 | } 1753 | }, 1754 | "node_modules/punycode": { 1755 | "version": "2.3.1", 1756 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1757 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1758 | "dev": true, 1759 | "engines": { 1760 | "node": ">=6" 1761 | } 1762 | }, 1763 | "node_modules/queue-microtask": { 1764 | "version": "1.2.3", 1765 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1766 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1767 | "dev": true, 1768 | "funding": [ 1769 | { 1770 | "type": "github", 1771 | "url": "https://github.com/sponsors/feross" 1772 | }, 1773 | { 1774 | "type": "patreon", 1775 | "url": "https://www.patreon.com/feross" 1776 | }, 1777 | { 1778 | "type": "consulting", 1779 | "url": "https://feross.org/support" 1780 | } 1781 | ] 1782 | }, 1783 | "node_modules/resolve-from": { 1784 | "version": "4.0.0", 1785 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1786 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1787 | "dev": true, 1788 | "engines": { 1789 | "node": ">=4" 1790 | } 1791 | }, 1792 | "node_modules/resolve-pkg-maps": { 1793 | "version": "1.0.0", 1794 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 1795 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 1796 | "dev": true, 1797 | "funding": { 1798 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 1799 | } 1800 | }, 1801 | "node_modules/reusify": { 1802 | "version": "1.0.4", 1803 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1804 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1805 | "dev": true, 1806 | "engines": { 1807 | "iojs": ">=1.0.0", 1808 | "node": ">=0.10.0" 1809 | } 1810 | }, 1811 | "node_modules/rimraf": { 1812 | "version": "3.0.2", 1813 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1814 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1815 | "dev": true, 1816 | "dependencies": { 1817 | "glob": "^7.1.3" 1818 | }, 1819 | "bin": { 1820 | "rimraf": "bin.js" 1821 | }, 1822 | "funding": { 1823 | "url": "https://github.com/sponsors/isaacs" 1824 | } 1825 | }, 1826 | "node_modules/run-parallel": { 1827 | "version": "1.2.0", 1828 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1829 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1830 | "dev": true, 1831 | "funding": [ 1832 | { 1833 | "type": "github", 1834 | "url": "https://github.com/sponsors/feross" 1835 | }, 1836 | { 1837 | "type": "patreon", 1838 | "url": "https://www.patreon.com/feross" 1839 | }, 1840 | { 1841 | "type": "consulting", 1842 | "url": "https://feross.org/support" 1843 | } 1844 | ], 1845 | "dependencies": { 1846 | "queue-microtask": "^1.2.2" 1847 | } 1848 | }, 1849 | "node_modules/semver": { 1850 | "version": "7.6.0", 1851 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", 1852 | "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", 1853 | "dev": true, 1854 | "dependencies": { 1855 | "lru-cache": "^6.0.0" 1856 | }, 1857 | "bin": { 1858 | "semver": "bin/semver.js" 1859 | }, 1860 | "engines": { 1861 | "node": ">=10" 1862 | } 1863 | }, 1864 | "node_modules/semver/node_modules/lru-cache": { 1865 | "version": "6.0.0", 1866 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1867 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1868 | "dev": true, 1869 | "dependencies": { 1870 | "yallist": "^4.0.0" 1871 | }, 1872 | "engines": { 1873 | "node": ">=10" 1874 | } 1875 | }, 1876 | "node_modules/semver/node_modules/yallist": { 1877 | "version": "4.0.0", 1878 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1879 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 1880 | "dev": true 1881 | }, 1882 | "node_modules/shebang-command": { 1883 | "version": "2.0.0", 1884 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1885 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1886 | "dev": true, 1887 | "dependencies": { 1888 | "shebang-regex": "^3.0.0" 1889 | }, 1890 | "engines": { 1891 | "node": ">=8" 1892 | } 1893 | }, 1894 | "node_modules/shebang-regex": { 1895 | "version": "3.0.0", 1896 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1897 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1898 | "dev": true, 1899 | "engines": { 1900 | "node": ">=8" 1901 | } 1902 | }, 1903 | "node_modules/slash": { 1904 | "version": "3.0.0", 1905 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 1906 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 1907 | "dev": true, 1908 | "engines": { 1909 | "node": ">=8" 1910 | } 1911 | }, 1912 | "node_modules/strip-ansi": { 1913 | "version": "6.0.1", 1914 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1915 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1916 | "dev": true, 1917 | "dependencies": { 1918 | "ansi-regex": "^5.0.1" 1919 | }, 1920 | "engines": { 1921 | "node": ">=8" 1922 | } 1923 | }, 1924 | "node_modules/strip-json-comments": { 1925 | "version": "3.1.1", 1926 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1927 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1928 | "dev": true, 1929 | "engines": { 1930 | "node": ">=8" 1931 | }, 1932 | "funding": { 1933 | "url": "https://github.com/sponsors/sindresorhus" 1934 | } 1935 | }, 1936 | "node_modules/supports-color": { 1937 | "version": "7.2.0", 1938 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1939 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1940 | "dev": true, 1941 | "dependencies": { 1942 | "has-flag": "^4.0.0" 1943 | }, 1944 | "engines": { 1945 | "node": ">=8" 1946 | } 1947 | }, 1948 | "node_modules/text-table": { 1949 | "version": "0.2.0", 1950 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1951 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1952 | "dev": true 1953 | }, 1954 | "node_modules/to-regex-range": { 1955 | "version": "5.0.1", 1956 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1957 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1958 | "dev": true, 1959 | "dependencies": { 1960 | "is-number": "^7.0.0" 1961 | }, 1962 | "engines": { 1963 | "node": ">=8.0" 1964 | } 1965 | }, 1966 | "node_modules/ts-api-utils": { 1967 | "version": "1.3.0", 1968 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", 1969 | "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", 1970 | "dev": true, 1971 | "engines": { 1972 | "node": ">=16" 1973 | }, 1974 | "peerDependencies": { 1975 | "typescript": ">=4.2.0" 1976 | } 1977 | }, 1978 | "node_modules/tsx": { 1979 | "version": "4.7.2", 1980 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", 1981 | "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==", 1982 | "dev": true, 1983 | "dependencies": { 1984 | "esbuild": "~0.19.10", 1985 | "get-tsconfig": "^4.7.2" 1986 | }, 1987 | "bin": { 1988 | "tsx": "dist/cli.mjs" 1989 | }, 1990 | "engines": { 1991 | "node": ">=18.0.0" 1992 | }, 1993 | "optionalDependencies": { 1994 | "fsevents": "~2.3.3" 1995 | } 1996 | }, 1997 | "node_modules/type-check": { 1998 | "version": "0.4.0", 1999 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2000 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2001 | "dev": true, 2002 | "dependencies": { 2003 | "prelude-ls": "^1.2.1" 2004 | }, 2005 | "engines": { 2006 | "node": ">= 0.8.0" 2007 | } 2008 | }, 2009 | "node_modules/type-fest": { 2010 | "version": "0.20.2", 2011 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 2012 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 2013 | "dev": true, 2014 | "engines": { 2015 | "node": ">=10" 2016 | }, 2017 | "funding": { 2018 | "url": "https://github.com/sponsors/sindresorhus" 2019 | } 2020 | }, 2021 | "node_modules/typescript": { 2022 | "version": "5.4.5", 2023 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 2024 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 2025 | "dev": true, 2026 | "bin": { 2027 | "tsc": "bin/tsc", 2028 | "tsserver": "bin/tsserver" 2029 | }, 2030 | "engines": { 2031 | "node": ">=14.17" 2032 | } 2033 | }, 2034 | "node_modules/undici-types": { 2035 | "version": "5.26.5", 2036 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 2037 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 2038 | "dev": true 2039 | }, 2040 | "node_modules/uri-js": { 2041 | "version": "4.4.1", 2042 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2043 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2044 | "dev": true, 2045 | "dependencies": { 2046 | "punycode": "^2.1.0" 2047 | } 2048 | }, 2049 | "node_modules/which": { 2050 | "version": "2.0.2", 2051 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2052 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2053 | "dev": true, 2054 | "dependencies": { 2055 | "isexe": "^2.0.0" 2056 | }, 2057 | "bin": { 2058 | "node-which": "bin/node-which" 2059 | }, 2060 | "engines": { 2061 | "node": ">= 8" 2062 | } 2063 | }, 2064 | "node_modules/wrappy": { 2065 | "version": "1.0.2", 2066 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2067 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2068 | "dev": true 2069 | }, 2070 | "node_modules/yocto-queue": { 2071 | "version": "0.1.0", 2072 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 2073 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 2074 | "dev": true, 2075 | "engines": { 2076 | "node": ">=10" 2077 | }, 2078 | "funding": { 2079 | "url": "https://github.com/sponsors/sindresorhus" 2080 | } 2081 | } 2082 | }, 2083 | "dependencies": { 2084 | "@aashutoshrathi/word-wrap": { 2085 | "version": "1.2.6", 2086 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", 2087 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", 2088 | "dev": true 2089 | }, 2090 | "@esbuild/aix-ppc64": { 2091 | "version": "0.19.12", 2092 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", 2093 | "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", 2094 | "dev": true, 2095 | "optional": true 2096 | }, 2097 | "@esbuild/android-arm": { 2098 | "version": "0.19.12", 2099 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", 2100 | "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", 2101 | "dev": true, 2102 | "optional": true 2103 | }, 2104 | "@esbuild/android-arm64": { 2105 | "version": "0.19.12", 2106 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", 2107 | "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", 2108 | "dev": true, 2109 | "optional": true 2110 | }, 2111 | "@esbuild/android-x64": { 2112 | "version": "0.19.12", 2113 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", 2114 | "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", 2115 | "dev": true, 2116 | "optional": true 2117 | }, 2118 | "@esbuild/darwin-arm64": { 2119 | "version": "0.19.12", 2120 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", 2121 | "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", 2122 | "dev": true, 2123 | "optional": true 2124 | }, 2125 | "@esbuild/darwin-x64": { 2126 | "version": "0.19.12", 2127 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", 2128 | "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", 2129 | "dev": true, 2130 | "optional": true 2131 | }, 2132 | "@esbuild/freebsd-arm64": { 2133 | "version": "0.19.12", 2134 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", 2135 | "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", 2136 | "dev": true, 2137 | "optional": true 2138 | }, 2139 | "@esbuild/freebsd-x64": { 2140 | "version": "0.19.12", 2141 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", 2142 | "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", 2143 | "dev": true, 2144 | "optional": true 2145 | }, 2146 | "@esbuild/linux-arm": { 2147 | "version": "0.19.12", 2148 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", 2149 | "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", 2150 | "dev": true, 2151 | "optional": true 2152 | }, 2153 | "@esbuild/linux-arm64": { 2154 | "version": "0.19.12", 2155 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", 2156 | "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", 2157 | "dev": true, 2158 | "optional": true 2159 | }, 2160 | "@esbuild/linux-ia32": { 2161 | "version": "0.19.12", 2162 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", 2163 | "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", 2164 | "dev": true, 2165 | "optional": true 2166 | }, 2167 | "@esbuild/linux-loong64": { 2168 | "version": "0.19.12", 2169 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", 2170 | "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", 2171 | "dev": true, 2172 | "optional": true 2173 | }, 2174 | "@esbuild/linux-mips64el": { 2175 | "version": "0.19.12", 2176 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", 2177 | "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", 2178 | "dev": true, 2179 | "optional": true 2180 | }, 2181 | "@esbuild/linux-ppc64": { 2182 | "version": "0.19.12", 2183 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", 2184 | "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", 2185 | "dev": true, 2186 | "optional": true 2187 | }, 2188 | "@esbuild/linux-riscv64": { 2189 | "version": "0.19.12", 2190 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", 2191 | "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", 2192 | "dev": true, 2193 | "optional": true 2194 | }, 2195 | "@esbuild/linux-s390x": { 2196 | "version": "0.19.12", 2197 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", 2198 | "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", 2199 | "dev": true, 2200 | "optional": true 2201 | }, 2202 | "@esbuild/linux-x64": { 2203 | "version": "0.19.12", 2204 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", 2205 | "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", 2206 | "dev": true, 2207 | "optional": true 2208 | }, 2209 | "@esbuild/netbsd-x64": { 2210 | "version": "0.19.12", 2211 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", 2212 | "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", 2213 | "dev": true, 2214 | "optional": true 2215 | }, 2216 | "@esbuild/openbsd-x64": { 2217 | "version": "0.19.12", 2218 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", 2219 | "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", 2220 | "dev": true, 2221 | "optional": true 2222 | }, 2223 | "@esbuild/sunos-x64": { 2224 | "version": "0.19.12", 2225 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", 2226 | "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", 2227 | "dev": true, 2228 | "optional": true 2229 | }, 2230 | "@esbuild/win32-arm64": { 2231 | "version": "0.19.12", 2232 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", 2233 | "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", 2234 | "dev": true, 2235 | "optional": true 2236 | }, 2237 | "@esbuild/win32-ia32": { 2238 | "version": "0.19.12", 2239 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", 2240 | "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", 2241 | "dev": true, 2242 | "optional": true 2243 | }, 2244 | "@esbuild/win32-x64": { 2245 | "version": "0.19.12", 2246 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", 2247 | "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", 2248 | "dev": true, 2249 | "optional": true 2250 | }, 2251 | "@eslint-community/eslint-utils": { 2252 | "version": "4.4.0", 2253 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 2254 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 2255 | "dev": true, 2256 | "requires": { 2257 | "eslint-visitor-keys": "^3.3.0" 2258 | } 2259 | }, 2260 | "@eslint-community/regexpp": { 2261 | "version": "4.10.0", 2262 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", 2263 | "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", 2264 | "dev": true 2265 | }, 2266 | "@eslint/eslintrc": { 2267 | "version": "2.1.4", 2268 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", 2269 | "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", 2270 | "dev": true, 2271 | "requires": { 2272 | "ajv": "^6.12.4", 2273 | "debug": "^4.3.2", 2274 | "espree": "^9.6.0", 2275 | "globals": "^13.19.0", 2276 | "ignore": "^5.2.0", 2277 | "import-fresh": "^3.2.1", 2278 | "js-yaml": "^4.1.0", 2279 | "minimatch": "^3.1.2", 2280 | "strip-json-comments": "^3.1.1" 2281 | }, 2282 | "dependencies": { 2283 | "argparse": { 2284 | "version": "2.0.1", 2285 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 2286 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 2287 | "dev": true 2288 | }, 2289 | "js-yaml": { 2290 | "version": "4.1.0", 2291 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2292 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2293 | "dev": true, 2294 | "requires": { 2295 | "argparse": "^2.0.1" 2296 | } 2297 | } 2298 | } 2299 | }, 2300 | "@eslint/js": { 2301 | "version": "8.57.0", 2302 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", 2303 | "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", 2304 | "dev": true 2305 | }, 2306 | "@humanwhocodes/config-array": { 2307 | "version": "0.11.14", 2308 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", 2309 | "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", 2310 | "dev": true, 2311 | "requires": { 2312 | "@humanwhocodes/object-schema": "^2.0.2", 2313 | "debug": "^4.3.1", 2314 | "minimatch": "^3.0.5" 2315 | } 2316 | }, 2317 | "@humanwhocodes/module-importer": { 2318 | "version": "1.0.1", 2319 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 2320 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 2321 | "dev": true 2322 | }, 2323 | "@humanwhocodes/object-schema": { 2324 | "version": "2.0.3", 2325 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", 2326 | "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", 2327 | "dev": true 2328 | }, 2329 | "@nodelib/fs.scandir": { 2330 | "version": "2.1.5", 2331 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 2332 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 2333 | "dev": true, 2334 | "requires": { 2335 | "@nodelib/fs.stat": "2.0.5", 2336 | "run-parallel": "^1.1.9" 2337 | } 2338 | }, 2339 | "@nodelib/fs.stat": { 2340 | "version": "2.0.5", 2341 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 2342 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 2343 | "dev": true 2344 | }, 2345 | "@nodelib/fs.walk": { 2346 | "version": "1.2.8", 2347 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 2348 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 2349 | "dev": true, 2350 | "requires": { 2351 | "@nodelib/fs.scandir": "2.1.5", 2352 | "fastq": "^1.6.0" 2353 | } 2354 | }, 2355 | "@types/json-schema": { 2356 | "version": "7.0.15", 2357 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 2358 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 2359 | "dev": true 2360 | }, 2361 | "@types/node": { 2362 | "version": "20.12.7", 2363 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", 2364 | "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", 2365 | "dev": true, 2366 | "requires": { 2367 | "undici-types": "~5.26.4" 2368 | } 2369 | }, 2370 | "@types/semver": { 2371 | "version": "7.5.8", 2372 | "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", 2373 | "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", 2374 | "dev": true 2375 | }, 2376 | "@typescript-eslint/eslint-plugin": { 2377 | "version": "7.7.0", 2378 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz", 2379 | "integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==", 2380 | "dev": true, 2381 | "requires": { 2382 | "@eslint-community/regexpp": "^4.10.0", 2383 | "@typescript-eslint/scope-manager": "7.7.0", 2384 | "@typescript-eslint/type-utils": "7.7.0", 2385 | "@typescript-eslint/utils": "7.7.0", 2386 | "@typescript-eslint/visitor-keys": "7.7.0", 2387 | "debug": "^4.3.4", 2388 | "graphemer": "^1.4.0", 2389 | "ignore": "^5.3.1", 2390 | "natural-compare": "^1.4.0", 2391 | "semver": "^7.6.0", 2392 | "ts-api-utils": "^1.3.0" 2393 | } 2394 | }, 2395 | "@typescript-eslint/parser": { 2396 | "version": "7.7.0", 2397 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz", 2398 | "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==", 2399 | "dev": true, 2400 | "requires": { 2401 | "@typescript-eslint/scope-manager": "7.7.0", 2402 | "@typescript-eslint/types": "7.7.0", 2403 | "@typescript-eslint/typescript-estree": "7.7.0", 2404 | "@typescript-eslint/visitor-keys": "7.7.0", 2405 | "debug": "^4.3.4" 2406 | } 2407 | }, 2408 | "@typescript-eslint/scope-manager": { 2409 | "version": "7.7.0", 2410 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz", 2411 | "integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==", 2412 | "dev": true, 2413 | "requires": { 2414 | "@typescript-eslint/types": "7.7.0", 2415 | "@typescript-eslint/visitor-keys": "7.7.0" 2416 | } 2417 | }, 2418 | "@typescript-eslint/type-utils": { 2419 | "version": "7.7.0", 2420 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz", 2421 | "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==", 2422 | "dev": true, 2423 | "requires": { 2424 | "@typescript-eslint/typescript-estree": "7.7.0", 2425 | "@typescript-eslint/utils": "7.7.0", 2426 | "debug": "^4.3.4", 2427 | "ts-api-utils": "^1.3.0" 2428 | } 2429 | }, 2430 | "@typescript-eslint/types": { 2431 | "version": "7.7.0", 2432 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz", 2433 | "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==", 2434 | "dev": true 2435 | }, 2436 | "@typescript-eslint/typescript-estree": { 2437 | "version": "7.7.0", 2438 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz", 2439 | "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==", 2440 | "dev": true, 2441 | "requires": { 2442 | "@typescript-eslint/types": "7.7.0", 2443 | "@typescript-eslint/visitor-keys": "7.7.0", 2444 | "debug": "^4.3.4", 2445 | "globby": "^11.1.0", 2446 | "is-glob": "^4.0.3", 2447 | "minimatch": "^9.0.4", 2448 | "semver": "^7.6.0", 2449 | "ts-api-utils": "^1.3.0" 2450 | }, 2451 | "dependencies": { 2452 | "brace-expansion": { 2453 | "version": "2.0.1", 2454 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 2455 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 2456 | "dev": true, 2457 | "requires": { 2458 | "balanced-match": "^1.0.0" 2459 | } 2460 | }, 2461 | "minimatch": { 2462 | "version": "9.0.4", 2463 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", 2464 | "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", 2465 | "dev": true, 2466 | "requires": { 2467 | "brace-expansion": "^2.0.1" 2468 | } 2469 | } 2470 | } 2471 | }, 2472 | "@typescript-eslint/utils": { 2473 | "version": "7.7.0", 2474 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz", 2475 | "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==", 2476 | "dev": true, 2477 | "requires": { 2478 | "@eslint-community/eslint-utils": "^4.4.0", 2479 | "@types/json-schema": "^7.0.15", 2480 | "@types/semver": "^7.5.8", 2481 | "@typescript-eslint/scope-manager": "7.7.0", 2482 | "@typescript-eslint/types": "7.7.0", 2483 | "@typescript-eslint/typescript-estree": "7.7.0", 2484 | "semver": "^7.6.0" 2485 | } 2486 | }, 2487 | "@typescript-eslint/visitor-keys": { 2488 | "version": "7.7.0", 2489 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz", 2490 | "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==", 2491 | "dev": true, 2492 | "requires": { 2493 | "@typescript-eslint/types": "7.7.0", 2494 | "eslint-visitor-keys": "^3.4.3" 2495 | } 2496 | }, 2497 | "@ungap/structured-clone": { 2498 | "version": "1.2.0", 2499 | "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", 2500 | "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", 2501 | "dev": true 2502 | }, 2503 | "acorn": { 2504 | "version": "8.11.3", 2505 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 2506 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 2507 | "dev": true 2508 | }, 2509 | "acorn-jsx": { 2510 | "version": "5.3.2", 2511 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 2512 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 2513 | "dev": true, 2514 | "requires": {} 2515 | }, 2516 | "ajv": { 2517 | "version": "6.12.6", 2518 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 2519 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 2520 | "dev": true, 2521 | "requires": { 2522 | "fast-deep-equal": "^3.1.1", 2523 | "fast-json-stable-stringify": "^2.0.0", 2524 | "json-schema-traverse": "^0.4.1", 2525 | "uri-js": "^4.2.2" 2526 | } 2527 | }, 2528 | "ansi-regex": { 2529 | "version": "5.0.1", 2530 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2531 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2532 | "dev": true 2533 | }, 2534 | "ansi-styles": { 2535 | "version": "4.3.0", 2536 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2537 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2538 | "dev": true, 2539 | "requires": { 2540 | "color-convert": "^2.0.1" 2541 | } 2542 | }, 2543 | "array-union": { 2544 | "version": "2.1.0", 2545 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 2546 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 2547 | "dev": true 2548 | }, 2549 | "balanced-match": { 2550 | "version": "1.0.2", 2551 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 2552 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 2553 | "dev": true 2554 | }, 2555 | "brace-expansion": { 2556 | "version": "1.1.11", 2557 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 2558 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 2559 | "dev": true, 2560 | "requires": { 2561 | "balanced-match": "^1.0.0", 2562 | "concat-map": "0.0.1" 2563 | } 2564 | }, 2565 | "braces": { 2566 | "version": "3.0.2", 2567 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 2568 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 2569 | "dev": true, 2570 | "requires": { 2571 | "fill-range": "^7.0.1" 2572 | } 2573 | }, 2574 | "callsites": { 2575 | "version": "3.1.0", 2576 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 2577 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 2578 | "dev": true 2579 | }, 2580 | "chalk": { 2581 | "version": "4.1.2", 2582 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 2583 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 2584 | "dev": true, 2585 | "requires": { 2586 | "ansi-styles": "^4.1.0", 2587 | "supports-color": "^7.1.0" 2588 | } 2589 | }, 2590 | "color-convert": { 2591 | "version": "2.0.1", 2592 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2593 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2594 | "dev": true, 2595 | "requires": { 2596 | "color-name": "~1.1.4" 2597 | } 2598 | }, 2599 | "color-name": { 2600 | "version": "1.1.4", 2601 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2602 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2603 | "dev": true 2604 | }, 2605 | "concat-map": { 2606 | "version": "0.0.1", 2607 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 2608 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 2609 | "dev": true 2610 | }, 2611 | "cross-spawn": { 2612 | "version": "7.0.3", 2613 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 2614 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 2615 | "dev": true, 2616 | "requires": { 2617 | "path-key": "^3.1.0", 2618 | "shebang-command": "^2.0.0", 2619 | "which": "^2.0.1" 2620 | } 2621 | }, 2622 | "debug": { 2623 | "version": "4.3.4", 2624 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 2625 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 2626 | "dev": true, 2627 | "requires": { 2628 | "ms": "2.1.2" 2629 | } 2630 | }, 2631 | "deep-is": { 2632 | "version": "0.1.4", 2633 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 2634 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 2635 | "dev": true 2636 | }, 2637 | "dir-glob": { 2638 | "version": "3.0.1", 2639 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 2640 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 2641 | "dev": true, 2642 | "requires": { 2643 | "path-type": "^4.0.0" 2644 | } 2645 | }, 2646 | "doctrine": { 2647 | "version": "3.0.0", 2648 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 2649 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 2650 | "dev": true, 2651 | "requires": { 2652 | "esutils": "^2.0.2" 2653 | } 2654 | }, 2655 | "esbuild": { 2656 | "version": "0.19.12", 2657 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", 2658 | "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", 2659 | "dev": true, 2660 | "requires": { 2661 | "@esbuild/aix-ppc64": "0.19.12", 2662 | "@esbuild/android-arm": "0.19.12", 2663 | "@esbuild/android-arm64": "0.19.12", 2664 | "@esbuild/android-x64": "0.19.12", 2665 | "@esbuild/darwin-arm64": "0.19.12", 2666 | "@esbuild/darwin-x64": "0.19.12", 2667 | "@esbuild/freebsd-arm64": "0.19.12", 2668 | "@esbuild/freebsd-x64": "0.19.12", 2669 | "@esbuild/linux-arm": "0.19.12", 2670 | "@esbuild/linux-arm64": "0.19.12", 2671 | "@esbuild/linux-ia32": "0.19.12", 2672 | "@esbuild/linux-loong64": "0.19.12", 2673 | "@esbuild/linux-mips64el": "0.19.12", 2674 | "@esbuild/linux-ppc64": "0.19.12", 2675 | "@esbuild/linux-riscv64": "0.19.12", 2676 | "@esbuild/linux-s390x": "0.19.12", 2677 | "@esbuild/linux-x64": "0.19.12", 2678 | "@esbuild/netbsd-x64": "0.19.12", 2679 | "@esbuild/openbsd-x64": "0.19.12", 2680 | "@esbuild/sunos-x64": "0.19.12", 2681 | "@esbuild/win32-arm64": "0.19.12", 2682 | "@esbuild/win32-ia32": "0.19.12", 2683 | "@esbuild/win32-x64": "0.19.12" 2684 | } 2685 | }, 2686 | "escape-string-regexp": { 2687 | "version": "4.0.0", 2688 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 2689 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 2690 | "dev": true 2691 | }, 2692 | "eslint": { 2693 | "version": "8.57.0", 2694 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", 2695 | "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", 2696 | "dev": true, 2697 | "requires": { 2698 | "@eslint-community/eslint-utils": "^4.2.0", 2699 | "@eslint-community/regexpp": "^4.6.1", 2700 | "@eslint/eslintrc": "^2.1.4", 2701 | "@eslint/js": "8.57.0", 2702 | "@humanwhocodes/config-array": "^0.11.14", 2703 | "@humanwhocodes/module-importer": "^1.0.1", 2704 | "@nodelib/fs.walk": "^1.2.8", 2705 | "@ungap/structured-clone": "^1.2.0", 2706 | "ajv": "^6.12.4", 2707 | "chalk": "^4.0.0", 2708 | "cross-spawn": "^7.0.2", 2709 | "debug": "^4.3.2", 2710 | "doctrine": "^3.0.0", 2711 | "escape-string-regexp": "^4.0.0", 2712 | "eslint-scope": "^7.2.2", 2713 | "eslint-visitor-keys": "^3.4.3", 2714 | "espree": "^9.6.1", 2715 | "esquery": "^1.4.2", 2716 | "esutils": "^2.0.2", 2717 | "fast-deep-equal": "^3.1.3", 2718 | "file-entry-cache": "^6.0.1", 2719 | "find-up": "^5.0.0", 2720 | "glob-parent": "^6.0.2", 2721 | "globals": "^13.19.0", 2722 | "graphemer": "^1.4.0", 2723 | "ignore": "^5.2.0", 2724 | "imurmurhash": "^0.1.4", 2725 | "is-glob": "^4.0.0", 2726 | "is-path-inside": "^3.0.3", 2727 | "js-yaml": "^4.1.0", 2728 | "json-stable-stringify-without-jsonify": "^1.0.1", 2729 | "levn": "^0.4.1", 2730 | "lodash.merge": "^4.6.2", 2731 | "minimatch": "^3.1.2", 2732 | "natural-compare": "^1.4.0", 2733 | "optionator": "^0.9.3", 2734 | "strip-ansi": "^6.0.1", 2735 | "text-table": "^0.2.0" 2736 | }, 2737 | "dependencies": { 2738 | "argparse": { 2739 | "version": "2.0.1", 2740 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 2741 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 2742 | "dev": true 2743 | }, 2744 | "glob-parent": { 2745 | "version": "6.0.2", 2746 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 2747 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2748 | "dev": true, 2749 | "requires": { 2750 | "is-glob": "^4.0.3" 2751 | } 2752 | }, 2753 | "js-yaml": { 2754 | "version": "4.1.0", 2755 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2756 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2757 | "dev": true, 2758 | "requires": { 2759 | "argparse": "^2.0.1" 2760 | } 2761 | } 2762 | } 2763 | }, 2764 | "eslint-scope": { 2765 | "version": "7.2.2", 2766 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", 2767 | "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", 2768 | "dev": true, 2769 | "requires": { 2770 | "esrecurse": "^4.3.0", 2771 | "estraverse": "^5.2.0" 2772 | } 2773 | }, 2774 | "eslint-visitor-keys": { 2775 | "version": "3.4.3", 2776 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 2777 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 2778 | "dev": true 2779 | }, 2780 | "espree": { 2781 | "version": "9.6.1", 2782 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", 2783 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", 2784 | "dev": true, 2785 | "requires": { 2786 | "acorn": "^8.9.0", 2787 | "acorn-jsx": "^5.3.2", 2788 | "eslint-visitor-keys": "^3.4.1" 2789 | } 2790 | }, 2791 | "esquery": { 2792 | "version": "1.5.0", 2793 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 2794 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 2795 | "dev": true, 2796 | "requires": { 2797 | "estraverse": "^5.1.0" 2798 | } 2799 | }, 2800 | "esrecurse": { 2801 | "version": "4.3.0", 2802 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 2803 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 2804 | "dev": true, 2805 | "requires": { 2806 | "estraverse": "^5.2.0" 2807 | } 2808 | }, 2809 | "estraverse": { 2810 | "version": "5.3.0", 2811 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 2812 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 2813 | "dev": true 2814 | }, 2815 | "esutils": { 2816 | "version": "2.0.3", 2817 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 2818 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 2819 | "dev": true 2820 | }, 2821 | "fast-deep-equal": { 2822 | "version": "3.1.3", 2823 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 2824 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 2825 | "dev": true 2826 | }, 2827 | "fast-glob": { 2828 | "version": "3.3.2", 2829 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 2830 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 2831 | "dev": true, 2832 | "requires": { 2833 | "@nodelib/fs.stat": "^2.0.2", 2834 | "@nodelib/fs.walk": "^1.2.3", 2835 | "glob-parent": "^5.1.2", 2836 | "merge2": "^1.3.0", 2837 | "micromatch": "^4.0.4" 2838 | } 2839 | }, 2840 | "fast-json-stable-stringify": { 2841 | "version": "2.1.0", 2842 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 2843 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 2844 | "dev": true 2845 | }, 2846 | "fast-levenshtein": { 2847 | "version": "2.0.6", 2848 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 2849 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 2850 | "dev": true 2851 | }, 2852 | "fastq": { 2853 | "version": "1.17.1", 2854 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 2855 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 2856 | "dev": true, 2857 | "requires": { 2858 | "reusify": "^1.0.4" 2859 | } 2860 | }, 2861 | "file-entry-cache": { 2862 | "version": "6.0.1", 2863 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 2864 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 2865 | "dev": true, 2866 | "requires": { 2867 | "flat-cache": "^3.0.4" 2868 | } 2869 | }, 2870 | "fill-range": { 2871 | "version": "7.0.1", 2872 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 2873 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 2874 | "dev": true, 2875 | "requires": { 2876 | "to-regex-range": "^5.0.1" 2877 | } 2878 | }, 2879 | "find-up": { 2880 | "version": "5.0.0", 2881 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 2882 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 2883 | "dev": true, 2884 | "requires": { 2885 | "locate-path": "^6.0.0", 2886 | "path-exists": "^4.0.0" 2887 | } 2888 | }, 2889 | "flat-cache": { 2890 | "version": "3.2.0", 2891 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", 2892 | "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", 2893 | "dev": true, 2894 | "requires": { 2895 | "flatted": "^3.2.9", 2896 | "keyv": "^4.5.3", 2897 | "rimraf": "^3.0.2" 2898 | } 2899 | }, 2900 | "flatted": { 2901 | "version": "3.3.1", 2902 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", 2903 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", 2904 | "dev": true 2905 | }, 2906 | "fs.realpath": { 2907 | "version": "1.0.0", 2908 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 2909 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 2910 | "dev": true 2911 | }, 2912 | "fsevents": { 2913 | "version": "2.3.3", 2914 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 2915 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 2916 | "dev": true, 2917 | "optional": true 2918 | }, 2919 | "get-tsconfig": { 2920 | "version": "4.7.3", 2921 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", 2922 | "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", 2923 | "dev": true, 2924 | "requires": { 2925 | "resolve-pkg-maps": "^1.0.0" 2926 | } 2927 | }, 2928 | "glob": { 2929 | "version": "7.2.0", 2930 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 2931 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 2932 | "dev": true, 2933 | "requires": { 2934 | "fs.realpath": "^1.0.0", 2935 | "inflight": "^1.0.4", 2936 | "inherits": "2", 2937 | "minimatch": "^3.0.4", 2938 | "once": "^1.3.0", 2939 | "path-is-absolute": "^1.0.0" 2940 | } 2941 | }, 2942 | "glob-parent": { 2943 | "version": "5.1.2", 2944 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 2945 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 2946 | "dev": true, 2947 | "requires": { 2948 | "is-glob": "^4.0.1" 2949 | } 2950 | }, 2951 | "globals": { 2952 | "version": "13.24.0", 2953 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", 2954 | "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", 2955 | "dev": true, 2956 | "requires": { 2957 | "type-fest": "^0.20.2" 2958 | } 2959 | }, 2960 | "globby": { 2961 | "version": "11.1.0", 2962 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 2963 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 2964 | "dev": true, 2965 | "requires": { 2966 | "array-union": "^2.1.0", 2967 | "dir-glob": "^3.0.1", 2968 | "fast-glob": "^3.2.9", 2969 | "ignore": "^5.2.0", 2970 | "merge2": "^1.4.1", 2971 | "slash": "^3.0.0" 2972 | } 2973 | }, 2974 | "graphemer": { 2975 | "version": "1.4.0", 2976 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 2977 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 2978 | "dev": true 2979 | }, 2980 | "has-flag": { 2981 | "version": "4.0.0", 2982 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2983 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2984 | "dev": true 2985 | }, 2986 | "ignore": { 2987 | "version": "5.3.1", 2988 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", 2989 | "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", 2990 | "dev": true 2991 | }, 2992 | "import-fresh": { 2993 | "version": "3.3.0", 2994 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 2995 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 2996 | "dev": true, 2997 | "requires": { 2998 | "parent-module": "^1.0.0", 2999 | "resolve-from": "^4.0.0" 3000 | } 3001 | }, 3002 | "imurmurhash": { 3003 | "version": "0.1.4", 3004 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 3005 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 3006 | "dev": true 3007 | }, 3008 | "inflight": { 3009 | "version": "1.0.6", 3010 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 3011 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 3012 | "dev": true, 3013 | "requires": { 3014 | "once": "^1.3.0", 3015 | "wrappy": "1" 3016 | } 3017 | }, 3018 | "inherits": { 3019 | "version": "2.0.4", 3020 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 3021 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 3022 | "dev": true 3023 | }, 3024 | "is-extglob": { 3025 | "version": "2.1.1", 3026 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 3027 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 3028 | "dev": true 3029 | }, 3030 | "is-glob": { 3031 | "version": "4.0.3", 3032 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 3033 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 3034 | "dev": true, 3035 | "requires": { 3036 | "is-extglob": "^2.1.1" 3037 | } 3038 | }, 3039 | "is-number": { 3040 | "version": "7.0.0", 3041 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 3042 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 3043 | "dev": true 3044 | }, 3045 | "is-path-inside": { 3046 | "version": "3.0.3", 3047 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 3048 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 3049 | "dev": true 3050 | }, 3051 | "isexe": { 3052 | "version": "2.0.0", 3053 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 3054 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 3055 | "dev": true 3056 | }, 3057 | "json-buffer": { 3058 | "version": "3.0.1", 3059 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 3060 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 3061 | "dev": true 3062 | }, 3063 | "json-schema-traverse": { 3064 | "version": "0.4.1", 3065 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 3066 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 3067 | "dev": true 3068 | }, 3069 | "json-stable-stringify-without-jsonify": { 3070 | "version": "1.0.1", 3071 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 3072 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 3073 | "dev": true 3074 | }, 3075 | "keyv": { 3076 | "version": "4.5.4", 3077 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 3078 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 3079 | "dev": true, 3080 | "requires": { 3081 | "json-buffer": "3.0.1" 3082 | } 3083 | }, 3084 | "levn": { 3085 | "version": "0.4.1", 3086 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 3087 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 3088 | "dev": true, 3089 | "requires": { 3090 | "prelude-ls": "^1.2.1", 3091 | "type-check": "~0.4.0" 3092 | } 3093 | }, 3094 | "locate-path": { 3095 | "version": "6.0.0", 3096 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 3097 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 3098 | "dev": true, 3099 | "requires": { 3100 | "p-locate": "^5.0.0" 3101 | } 3102 | }, 3103 | "lodash.merge": { 3104 | "version": "4.6.2", 3105 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 3106 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 3107 | "dev": true 3108 | }, 3109 | "merge2": { 3110 | "version": "1.4.1", 3111 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 3112 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 3113 | "dev": true 3114 | }, 3115 | "micromatch": { 3116 | "version": "4.0.5", 3117 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 3118 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 3119 | "dev": true, 3120 | "requires": { 3121 | "braces": "^3.0.2", 3122 | "picomatch": "^2.3.1" 3123 | } 3124 | }, 3125 | "minimatch": { 3126 | "version": "3.1.2", 3127 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 3128 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 3129 | "dev": true, 3130 | "requires": { 3131 | "brace-expansion": "^1.1.7" 3132 | } 3133 | }, 3134 | "ms": { 3135 | "version": "2.1.2", 3136 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 3137 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 3138 | "dev": true 3139 | }, 3140 | "natural-compare": { 3141 | "version": "1.4.0", 3142 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 3143 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 3144 | "dev": true 3145 | }, 3146 | "once": { 3147 | "version": "1.4.0", 3148 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 3149 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 3150 | "dev": true, 3151 | "requires": { 3152 | "wrappy": "1" 3153 | } 3154 | }, 3155 | "optionator": { 3156 | "version": "0.9.3", 3157 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", 3158 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", 3159 | "dev": true, 3160 | "requires": { 3161 | "@aashutoshrathi/word-wrap": "^1.2.3", 3162 | "deep-is": "^0.1.3", 3163 | "fast-levenshtein": "^2.0.6", 3164 | "levn": "^0.4.1", 3165 | "prelude-ls": "^1.2.1", 3166 | "type-check": "^0.4.0" 3167 | } 3168 | }, 3169 | "p-limit": { 3170 | "version": "3.1.0", 3171 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 3172 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 3173 | "dev": true, 3174 | "requires": { 3175 | "yocto-queue": "^0.1.0" 3176 | } 3177 | }, 3178 | "p-locate": { 3179 | "version": "5.0.0", 3180 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 3181 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 3182 | "dev": true, 3183 | "requires": { 3184 | "p-limit": "^3.0.2" 3185 | } 3186 | }, 3187 | "parent-module": { 3188 | "version": "1.0.1", 3189 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 3190 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 3191 | "dev": true, 3192 | "requires": { 3193 | "callsites": "^3.0.0" 3194 | } 3195 | }, 3196 | "path-exists": { 3197 | "version": "4.0.0", 3198 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 3199 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 3200 | "dev": true 3201 | }, 3202 | "path-is-absolute": { 3203 | "version": "1.0.1", 3204 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 3205 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 3206 | "dev": true 3207 | }, 3208 | "path-key": { 3209 | "version": "3.1.1", 3210 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 3211 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 3212 | "dev": true 3213 | }, 3214 | "path-type": { 3215 | "version": "4.0.0", 3216 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 3217 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 3218 | "dev": true 3219 | }, 3220 | "picomatch": { 3221 | "version": "2.3.1", 3222 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 3223 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 3224 | "dev": true 3225 | }, 3226 | "prelude-ls": { 3227 | "version": "1.2.1", 3228 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 3229 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 3230 | "dev": true 3231 | }, 3232 | "punycode": { 3233 | "version": "2.3.1", 3234 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 3235 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 3236 | "dev": true 3237 | }, 3238 | "queue-microtask": { 3239 | "version": "1.2.3", 3240 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 3241 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 3242 | "dev": true 3243 | }, 3244 | "resolve-from": { 3245 | "version": "4.0.0", 3246 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 3247 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 3248 | "dev": true 3249 | }, 3250 | "resolve-pkg-maps": { 3251 | "version": "1.0.0", 3252 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 3253 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 3254 | "dev": true 3255 | }, 3256 | "reusify": { 3257 | "version": "1.0.4", 3258 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 3259 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 3260 | "dev": true 3261 | }, 3262 | "rimraf": { 3263 | "version": "3.0.2", 3264 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 3265 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 3266 | "dev": true, 3267 | "requires": { 3268 | "glob": "^7.1.3" 3269 | } 3270 | }, 3271 | "run-parallel": { 3272 | "version": "1.2.0", 3273 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 3274 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 3275 | "dev": true, 3276 | "requires": { 3277 | "queue-microtask": "^1.2.2" 3278 | } 3279 | }, 3280 | "semver": { 3281 | "version": "7.6.0", 3282 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", 3283 | "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", 3284 | "dev": true, 3285 | "requires": { 3286 | "lru-cache": "^6.0.0" 3287 | }, 3288 | "dependencies": { 3289 | "lru-cache": { 3290 | "version": "6.0.0", 3291 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 3292 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 3293 | "dev": true, 3294 | "requires": { 3295 | "yallist": "^4.0.0" 3296 | } 3297 | }, 3298 | "yallist": { 3299 | "version": "4.0.0", 3300 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 3301 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 3302 | "dev": true 3303 | } 3304 | } 3305 | }, 3306 | "shebang-command": { 3307 | "version": "2.0.0", 3308 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 3309 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 3310 | "dev": true, 3311 | "requires": { 3312 | "shebang-regex": "^3.0.0" 3313 | } 3314 | }, 3315 | "shebang-regex": { 3316 | "version": "3.0.0", 3317 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 3318 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 3319 | "dev": true 3320 | }, 3321 | "slash": { 3322 | "version": "3.0.0", 3323 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 3324 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 3325 | "dev": true 3326 | }, 3327 | "strip-ansi": { 3328 | "version": "6.0.1", 3329 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 3330 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 3331 | "dev": true, 3332 | "requires": { 3333 | "ansi-regex": "^5.0.1" 3334 | } 3335 | }, 3336 | "strip-json-comments": { 3337 | "version": "3.1.1", 3338 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 3339 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 3340 | "dev": true 3341 | }, 3342 | "supports-color": { 3343 | "version": "7.2.0", 3344 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 3345 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 3346 | "dev": true, 3347 | "requires": { 3348 | "has-flag": "^4.0.0" 3349 | } 3350 | }, 3351 | "text-table": { 3352 | "version": "0.2.0", 3353 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 3354 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 3355 | "dev": true 3356 | }, 3357 | "to-regex-range": { 3358 | "version": "5.0.1", 3359 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 3360 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 3361 | "dev": true, 3362 | "requires": { 3363 | "is-number": "^7.0.0" 3364 | } 3365 | }, 3366 | "ts-api-utils": { 3367 | "version": "1.3.0", 3368 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", 3369 | "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", 3370 | "dev": true, 3371 | "requires": {} 3372 | }, 3373 | "tsx": { 3374 | "version": "4.7.2", 3375 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz", 3376 | "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==", 3377 | "dev": true, 3378 | "requires": { 3379 | "esbuild": "~0.19.10", 3380 | "fsevents": "~2.3.3", 3381 | "get-tsconfig": "^4.7.2" 3382 | } 3383 | }, 3384 | "type-check": { 3385 | "version": "0.4.0", 3386 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 3387 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 3388 | "dev": true, 3389 | "requires": { 3390 | "prelude-ls": "^1.2.1" 3391 | } 3392 | }, 3393 | "type-fest": { 3394 | "version": "0.20.2", 3395 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 3396 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 3397 | "dev": true 3398 | }, 3399 | "typescript": { 3400 | "version": "5.4.5", 3401 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 3402 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 3403 | "dev": true 3404 | }, 3405 | "undici-types": { 3406 | "version": "5.26.5", 3407 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 3408 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 3409 | "dev": true 3410 | }, 3411 | "uri-js": { 3412 | "version": "4.4.1", 3413 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 3414 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 3415 | "dev": true, 3416 | "requires": { 3417 | "punycode": "^2.1.0" 3418 | } 3419 | }, 3420 | "which": { 3421 | "version": "2.0.2", 3422 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 3423 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 3424 | "dev": true, 3425 | "requires": { 3426 | "isexe": "^2.0.0" 3427 | } 3428 | }, 3429 | "wrappy": { 3430 | "version": "1.0.2", 3431 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3432 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 3433 | "dev": true 3434 | }, 3435 | "yocto-queue": { 3436 | "version": "0.1.0", 3437 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 3438 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 3439 | "dev": true 3440 | } 3441 | } 3442 | } 3443 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bigint-money", 3 | "version": "2.0.0", 4 | "description": "A Money class for high precision calculations using the ESnext bigint type.", 5 | "main": "dist/index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "make test", 9 | "prepublishOnly": "make build" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+ssh://git@github.com/evert/bigint-money.git" 14 | }, 15 | "keywords": [ 16 | "money", 17 | "finance", 18 | "fixed-point", 19 | "currency", 20 | "bigint" 21 | ], 22 | "author": "Evert Pot", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/evert/bigint-money/issues" 26 | }, 27 | "homepage": "https://github.com/evert/bigint-money#readme", 28 | "devDependencies": { 29 | "@types/node": "^20.12.7", 30 | "@typescript-eslint/eslint-plugin": "^7.7.0", 31 | "@typescript-eslint/parser": "^7.7.0", 32 | "eslint": "^8.57.0", 33 | "tsx": "^4.7.2", 34 | "typescript": "^5.4.5" 35 | }, 36 | "nyc": { 37 | "extension": [ 38 | ".ts" 39 | ] 40 | }, 41 | "files": [ 42 | "browser", 43 | "dist", 44 | "LICENSE", 45 | "readme.md" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | bigint-money 2 | ============ 3 | 4 | This library can be used for doing math with Money. Key features: 5 | 6 | * Uses the Ecmascript [bigint][2] type. 7 | * Written in Typescript. 8 | * Loosely follows [Martin Fowler's Money Type][3] from 9 | ["Patterns of Enterprise Application Architecture"][4]. 10 | * Faster than Money packages that use non-native bigdecimal libraries. 11 | * All rounding is done via the ["Bankers Rounding"][6] (a.k.a. "round 12 | half to even") by default, but different rounding strategies can be 13 | specified. 14 | * Uses 20 decimals for all calculations. 15 | 16 | 17 | Benchmark 18 | --------- 19 | 20 | Most 'money' libraries on NPM only use 2 digits for precision, or use 21 | Javacript's "number" and will quickly overflow. 22 | 23 | The only comparible library I found was [big-money][7]. It's probably 24 | the best alternative if your Javascript environment doesn't have support 25 | for `bigint` yet. 26 | 27 | My simple benchmark calculates a ledger with 1 million entries. 28 | 29 | ``` 30 | bigint-money | big-money 31 | ledger 816 ms | 43.201 ms 32 | % 100 % | 5294 % 33 | ``` 34 | 35 | If you want to run it yourself, you can find my test script in the `bench/` 36 | directory. 37 | 38 | 39 | Installation 40 | ------------ 41 | 42 | npm i bigint-money 43 | 44 | Usage 45 | ----- 46 | 47 | Creating a money object. 48 | 49 | ```javascript 50 | import Money from 'bigint-money'; 51 | const foo = new Money('5', 'USD'); 52 | ``` 53 | 54 | It's possible to create a new money object with a Number as well 55 | 56 | ```javascript 57 | const foo = new Money(5, 'USD'); 58 | ``` 59 | 60 | However, if you pass it a number that's 'unsafe' such as a float, 61 | an error will be thrown: 62 | 63 | ```javascript 64 | const foo = new Money(.5, 'USD'); 65 | // UnsafeIntegerException 66 | ``` 67 | 68 | Once you have a `Money` object, you can use `toFixed()` to output 69 | a string. 70 | 71 | ```javascript 72 | const foo = new Money('5', 'USD'); 73 | console.log(foo.toFixed(2)); // 5.00 74 | ``` 75 | 76 | ### Arithmetic 77 | 78 | You can use `.add()` and `.subtract()` on it: 79 | 80 | ```javascript 81 | const foo = new Money('5', 'USD'); 82 | const bar = foo.add('10'); 83 | ``` 84 | 85 | All `Money` objects are immutable. Calling those functions does 86 | not change the original value: 87 | 88 | ```javascript 89 | console.log(foo.toFixed(2), bar.toFixed(2)); 90 | // 5.00 1.00 91 | ``` 92 | 93 | You can also pass `Money` objects to `subtract` and `add`: 94 | 95 | ```javascript 96 | const startBalance = new Money(1000, 'USD'); 97 | const salary = new Money(2000, 'USD'); 98 | const newBalance = startBalance.add(salary); 99 | ``` 100 | 101 | If you try to add money from different currencies, an error 102 | will be thrown: 103 | 104 | ```javascript 105 | new Money(1000, 'USD').add( new Money( 50000, 'YEN' )); 106 | // IncompatibleCurencyError 107 | ``` 108 | 109 | Division and multiplication: 110 | 111 | ```javascript 112 | // Division 113 | const result = new Money(10).divide(3); 114 | 115 | // Multiplication 116 | const result = new Money('2000').multiply('1.25'); 117 | 118 | // Powers 119 | const result = new Money(2).pow(8); 120 | ``` 121 | 122 | ### Comparing objects 123 | 124 | The Money object has the following functions for comparisons: 125 | 126 | * `isLesserThan` 127 | * `isGreaterThan` 128 | * `isEqual` 129 | * `isLesserThanOrEqual` 130 | * `isGreaterThanOrEqual` 131 | 132 | All of them can take a (safe) number, a string or another `Money` object and 133 | return a boolean. 134 | 135 | There is also a `compare()` function that returns `-1`, `0` or `-1` depending 136 | on if the passed argument was more, equal or less than the object. 137 | 138 | ```javascript 139 | const money1 = new Money('1.00', 'EUR'); 140 | 141 | money.compare(2); // Returns -1 142 | money.compare(1); // Returns 0 143 | money.compare(0); // Returns 1 144 | 145 | money.compare('0.01'); // returns -1 146 | money.compare(new Money('1.000005', 'EUR')); // returns 1 147 | 148 | money.compare(new Money('1', 'CAD')); // throws IncompatibleCurrencyError 149 | ``` 150 | 151 | The idea is that if the object is smaller than the passed one, `-1` returned. 152 | `0` is returned if they're equal and `1` is returned if the passed value is 153 | higher. 154 | 155 | 156 | This makes it easy to sort: 157 | 158 | ```javascript 159 | const values = [ 160 | new Money('1', 'USD'), 161 | new Money('2', 'USD') 162 | ]; 163 | 164 | values.sort( (a, b) => a.compare(b) ); 165 | ``` 166 | 167 | ### Allocate 168 | 169 | When splitting money in parts, it might be possible to lose a penny. 170 | For example, when dividing $1 between 3 people, each person gets 171 | `$ 0.33` but there's a spare `$ 0.01`. 172 | 173 | The allocate function splits a Money value in even parts, but the 174 | remainder is distributed over the parts round-robin. 175 | 176 | ```javascript 177 | const earnings = new Money(100, 'USD'); 178 | 179 | console.log( 180 | earnings.allocate(3, 2); 181 | ); 182 | 183 | // Results in 3 Money objects: 184 | // 33.34 185 | // 33.33 186 | // 33.33 187 | ``` 188 | 189 | Splitting debts (negative values) also works as expected. 190 | 191 | The second argument of the allocate function is the precision. Basically the 192 | number of digits you are interested in. 193 | 194 | For USD and most currencies this is 2. It's required to pass this argument 195 | because the Money object can't guess the desired precision. 196 | 197 | ### Rounding 198 | 199 | By default this library uses 'round half to even' aka 'bankers rounding', but 200 | a different rounding method may be specified in the constructor. 201 | 202 | ```javascript 203 | import { Money, Round } from 'bigint-money'; 204 | const m = new Money(100, 'USD', Round.HALF_AWAY_FROM_0); 205 | ``` 206 | 207 | Common rounding techniques round to the nearest integer, but require a 208 | tie-breaker for the `0.5` case. These are rounding options for that case: 209 | 210 | * `Round.HALF_TO_EVEN` - The default 211 | * `Round.BANKERS` - Alias of 'HALF_TO_EVEN' 212 | * `Round.AWAY_FROM_0` - Round away from 0. (up if positive, down if negative) 213 | * `Round.HALF_TOWARDS_0` - Round towards 0. (down if positive, up if negative). 214 | 215 | These rounding options don't always go the nearest integer 216 | 217 | * `Round.TOWARDS_0` - Always rounds towards 0. This effectively just drops the 218 | fraction. 219 | * `Round.TRUNCATE` - Alias for `TOWARDS_0`. 220 | 221 | Why is this library needed? 222 | --------------------------- 223 | 224 | ### Floating points and money 225 | 226 | Using floating points for money can be problematic when rounding, 227 | you don't always get what you expect. 228 | 229 | Because of this, developers tend to multiply their currencies 230 | by a 100, so instead of 5 dollars, they might count 500 cents. 231 | 232 | This ensures that there are no rounding problems. 233 | 234 | However, this might start to get problematic if a lot of digits 235 | are needed. Javascript automatically converts integers to floats 236 | once they are larger than 9,007,199,254,740,991. 237 | 238 | When counting cents instead of dollars, this still gives us a 239 | maximum of 90 trillion dollars. Some financial calculations 240 | require more more precision than cents though. 241 | 242 | For example, there are cryptocurrencies such as Monero that 243 | count up 12 digits. This means if we want to precisely count 244 | monero, this gives us a maxium of 9007 monero, which currently 245 | is around $390,000 USD. 246 | 247 | Even in traditional accounting and finance, it might be required 248 | to have more significant digits. 249 | 250 | ### Bigint libraries in javascript 251 | 252 | Traditionally this is solved in Javascript by using one of the 253 | 'bigint' or bignumber' libraries. Some examples: 254 | 255 | * [big-integer](https://www.npmjs.com/package/big-integer) 256 | * [big-number](https://www.npmjs.com/package/big-number) 257 | 258 | The way these libraries work is that they use strings for numbers, 259 | split the number up somehow and do arthimetic sometimes 1 digit 260 | at a time. 261 | 262 | This is fairly complex, and not very fast. 263 | 264 | ### Bigint in EcmaScript 265 | 266 | Future versions of Ecmascript will have support for a [bigint][1] type. This 267 | type is a new type of 'number', but unlike the 'Number' type it 268 | doesn't automatically convert to floating point numbers and can 269 | be extremely large. 270 | 271 | The way you might see a bigint in a source file is like this: 272 | 273 | ```javascript 274 | const foo = 10n + 5n; 275 | ``` 276 | 277 | The `n` prefix tells the javascript engine this is no `Number`, 278 | but a `Bigint`. 279 | 280 | There's a lot more info on the [Google Blog][2]. 281 | 282 | 283 | [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt 284 | [2]: https://developers.google.com/web/updates/2018/05/bigint 285 | [3]: https://martinfowler.com/eaaCatalog/money.html 286 | [4]: https://amzn.to/2EezezD "Note: affiliate link" 287 | [6]: http://wiki.c2.com/?BankersRounding 288 | [7]: https://www.npmjs.com/package/big-money 289 | -------------------------------------------------------------------------------- /src/errors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Thrown when trying to use unsafe integers. 3 | * 4 | * These require explicit conversions first. 5 | */ 6 | export class UnsafeIntegerError extends Error { } 7 | 8 | /** 9 | * Thrown when, for example trying to add USD to YEN 10 | */ 11 | export class IncompatibleCurrencyError extends Error { } 12 | 13 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { Money, Money as default } from './money.js'; 2 | export { IncompatibleCurrencyError, UnsafeIntegerError } from './errors.js'; 3 | export { Round } from './util.js'; 4 | -------------------------------------------------------------------------------- /src/money.ts: -------------------------------------------------------------------------------- 1 | import { IncompatibleCurrencyError } from './errors.js'; 2 | import { 3 | bigintToFixed, 4 | divide, 5 | moneyValueToBigInt, 6 | PRECISION, 7 | PRECISION_I, 8 | PRECISION_M, 9 | Round, 10 | } from './util.js'; 11 | 12 | export class Money { 13 | 14 | currency: string; 15 | private value: bigint; 16 | private round: Round; 17 | 18 | constructor(value: number | bigint | string, currency: string, round: Round = Round.HALF_TO_EVEN) { 19 | 20 | this.currency = currency; 21 | this.round = round; 22 | this.value = moneyValueToBigInt(value, this.round); 23 | 24 | } 25 | 26 | /** 27 | * Return a string representation of the money value. 28 | * 29 | * Precision is a number of decimals that was requested. The decimals are 30 | * always returned, e.g.: new Money(1, 'USD').toFixed(2) returns '1.00'. 31 | * 32 | * This function rounds to even, a.k.a. it uses bankers rounding. 33 | */ 34 | toFixed(precision: number): string { 35 | 36 | return bigintToFixed(this.value, precision, this.round); 37 | 38 | } 39 | 40 | add(val: Money | number | string): Money { 41 | 42 | if (val instanceof Money && val.currency !== this.currency) { 43 | throw new IncompatibleCurrencyError('You cannot add Money from different currencies. Convert first'); 44 | } 45 | 46 | const addVal = moneyValueToBigInt(val, this.round); 47 | const r = Money.fromSource(addVal + this.value, this.currency, this.round); 48 | return r; 49 | 50 | } 51 | 52 | subtract(val: Money | number | string): Money { 53 | 54 | if (val instanceof Money && val.currency !== this.currency) { 55 | throw new IncompatibleCurrencyError('You cannot subtract Money from different currencies. Convert first'); 56 | } 57 | 58 | const subVal = moneyValueToBigInt(val, this.round); 59 | return Money.fromSource(this.value - subVal, this.currency, this.round); 60 | 61 | } 62 | 63 | /** 64 | * Divide the current number with the specified number. 65 | * 66 | * This function returns a new Money object with the result. 67 | * 68 | * Unlike add, subtract, divide and multiply do accept mismatching 69 | * currencies. When calling divide, the currency of _this_ Money object will 70 | * be used for the resulting object. 71 | */ 72 | divide(val: number | string | Money): Money { 73 | 74 | // Even though val1 was already in 'bigint' format, we run this 75 | // again as otherwise we will lose precision. 76 | // 77 | // This means for an original of $1 this would now be $1 * 10**24. 78 | const val1 = moneyValueToBigInt(this.value, this.round); 79 | 80 | // Converting the dividor. 81 | const val2 = moneyValueToBigInt(val, this.round); 82 | 83 | return Money.fromSource( 84 | divide(val1, val2, this.round), 85 | this.currency, 86 | this.round, 87 | ); 88 | 89 | } 90 | 91 | /** 92 | * Multiply 93 | * 94 | * Unlike add, subtract, divide and multiply do accept mismatching 95 | * currencies. When calling multiply, the currency of _this_ Money object will 96 | * be used for the resulting object. 97 | */ 98 | multiply(val: number | string | Money): Money { 99 | 100 | const valBig = moneyValueToBigInt(val, this.round); 101 | 102 | // Converting the dividor. 103 | const resultBig = valBig * this.value; 104 | 105 | return Money.fromSource( 106 | divide(resultBig, PRECISION_M, this.round), 107 | this.currency, 108 | this.round, 109 | ); 110 | 111 | } 112 | 113 | /** 114 | * Pow returns the current value to it's exponent. 115 | * 116 | * pow currently only supports whole numbers. 117 | */ 118 | pow(exponent: number | bigint): Money { 119 | 120 | if (typeof exponent === 'number' && !Number.isInteger(exponent)) { 121 | throw new Error('You can currently only use pow() with whole numbers'); 122 | } 123 | 124 | if (exponent > 1) { 125 | const resultBig = this.value ** BigInt(exponent); 126 | return Money.fromSource( 127 | divide(resultBig, PRECISION_M ** (BigInt(exponent)-1n), this.round), 128 | this.currency, 129 | this.round 130 | ); 131 | } else if (exponent < 0) { 132 | return new Money(1, this.currency, this.round).divide(this.pow(-exponent)); 133 | } else if (exponent === 1) { 134 | return this; 135 | } else { 136 | return new Money(1, this.currency, this.round); 137 | } 138 | } 139 | 140 | /** 141 | * Returns the absolute value. 142 | */ 143 | abs(): Money { 144 | 145 | return this.multiply(this.sign()); 146 | 147 | } 148 | 149 | /** 150 | * Return -1 if the value is less than zero, 0 if zero, and 1 if more than zero. 151 | */ 152 | sign(): number { 153 | 154 | return this.compare(0); 155 | 156 | } 157 | 158 | /** 159 | * Returns true if this Money object is _less_ than the passed value 160 | */ 161 | isLesserThan(val: number | string | Money): boolean { 162 | 163 | return this.compare(val) === -1; 164 | 165 | } 166 | 167 | /** 168 | * Returns true if this Money object is _more_ than the passed value 169 | */ 170 | isGreaterThan(val: number | string | Money): boolean { 171 | 172 | return this.compare(val) === 1; 173 | 174 | } 175 | 176 | /** 177 | * Returns true if this Money object is _more_ than the passed value 178 | */ 179 | isEqual(val: number | string | Money): boolean { 180 | 181 | return this.compare(val) === 0; 182 | 183 | } 184 | 185 | /** 186 | * Returns true if this Money object is _more_ than the passed value 187 | */ 188 | isLesserThanOrEqual(val: number | string | Money): boolean { 189 | 190 | return this.compare(val) < 1; 191 | 192 | } 193 | 194 | /** 195 | * Returns true if this Money object is _more_ than the passed value 196 | */ 197 | isGreaterThanOrEqual(val: number | string | Money): boolean { 198 | 199 | return this.compare(val) > -1; 200 | 201 | } 202 | 203 | /** 204 | * Compares this Money object with another value. 205 | * 206 | * If the values are equal, 0 is returned. 207 | * If this object is considered to be lower, -1 is returned. 208 | * If this object is considered to be higher, 1 is returned. 209 | */ 210 | compare(val: number | string | Money): -1 | 0 | 1 { 211 | 212 | if (val instanceof Money && val.currency !== this.currency) { 213 | throw new IncompatibleCurrencyError('You cannot compare different currencies.'); 214 | } 215 | 216 | const bigVal = moneyValueToBigInt(val, this.round); 217 | if (bigVal === this.value) { return 0; } 218 | return this.value < bigVal ? -1 : 1; 219 | 220 | } 221 | 222 | 223 | /** 224 | * Allocate this value to different parts. 225 | * 226 | * This is useful in cases no money can be lost when splitting in different 227 | * parts. For example, when splitting $1 between 3 people, this function will 228 | * return 3.34, 3.33, 3.33. 229 | * 230 | * The remainder of the split will be added round-robin to the results, 231 | * starting with the first group. 232 | * 233 | * The reason precision must be specified, is because under the hood this 234 | * library uses 12 digits for precision. But when splitting a whole dollar, 235 | * you might only be interested in cents (precision = 2). 236 | * 237 | * 238 | */ 239 | allocate(parts: number, precision: number): Money[] { 240 | 241 | const bParts = BigInt(parts); 242 | 243 | // Javascript will round to 0. 244 | const fraction = this.value / bParts; 245 | const remainder = this.value % bParts; 246 | 247 | // This value is used for rounding to the desired precision 248 | const precisionRounder = BigInt(10) ** (PRECISION - BigInt(precision)); 249 | 250 | const roundedFraction = (fraction / precisionRounder); 251 | const roundedRemainder = fraction % precisionRounder; 252 | 253 | // We had 2 division operators, and we want to keep remainders for both 254 | // of them. 255 | const totalRoundedRemainder = ((roundedRemainder + remainder) * bParts) / precisionRounder; 256 | 257 | const result: bigint[] = Array(parts).fill(roundedFraction); 258 | 259 | // Figure out how many spare 'cents' we need to distribute. If the number 260 | // is negative, we need to spread debt instead. 261 | const add = BigInt(totalRoundedRemainder > 0 ? 1 : -1); 262 | 263 | for (let i = 0; i < Math.abs(Number(totalRoundedRemainder)); i++) { 264 | result[i] += add; 265 | } 266 | 267 | return result.map( item => { 268 | 269 | return Money.fromSource( 270 | item * precisionRounder, 271 | this.currency, 272 | this.round 273 | ); 274 | 275 | }); 276 | 277 | } 278 | 279 | /** 280 | * Returns the underlying bigint value. 281 | * 282 | * This is the current value of the object, multiplied by 10 ** 12. 283 | */ 284 | toSource(): bigint { 285 | 286 | return this.value; 287 | 288 | } 289 | 290 | /** 291 | * A factory function to construct a Money object a 'source' value. 292 | * 293 | * The source value is just the underlying bigint used in the Money 294 | * class and can be obtained by calling Money.getSource(). 295 | */ 296 | static fromSource(val: bigint, currency: string, round: Round = Round.HALF_TO_EVEN): Money { 297 | 298 | const m = new Money(0, currency, round); 299 | m.value = val; 300 | 301 | return m; 302 | 303 | } 304 | 305 | /** 306 | * This function creates custom output in console.log statements. 307 | */ 308 | [Symbol.for('nodejs.util.inspect.custom')](): string { 309 | 310 | return this.format() + ' ' + this.currency; 311 | 312 | } 313 | 314 | /** 315 | * A default output for serializing to JSON 316 | */ 317 | toJSON(): [string, string] { 318 | 319 | return [this.format(), this.currency]; 320 | 321 | } 322 | 323 | /** 324 | * This function will return a string with all irrelevant 0's removed. 325 | */ 326 | format(): string { 327 | 328 | return this.toFixed(PRECISION_I).replace(/\.?0+$/, ''); 329 | 330 | } 331 | 332 | } 333 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import { UnsafeIntegerError } from './errors.js'; 2 | import { Money } from './money.js'; 3 | 4 | // How many digits we support 5 | export const PRECISION_I = 20; 6 | 7 | // bigint version. We keep both so there's less conversions. 8 | export const PRECISION = BigInt(PRECISION_I); 9 | 10 | // Multiplication factor for internal values 11 | export const PRECISION_M = 10n ** PRECISION; 12 | 13 | export enum Round { 14 | 15 | // The following rules are round to the nearest integer, but have different 16 | // rules for when it's right in the middle (.5). 17 | HALF_TO_EVEN = 1, 18 | // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values 19 | BANKERS = 1, // Alias 20 | HALF_AWAY_FROM_0 = 2, 21 | HALF_TOWARDS_0 = 3, 22 | 23 | // These cases don't always round to the nearest integer 24 | TOWARDS_0 = 11, // Effectively drops the fractional part 25 | // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values 26 | TRUNCATE = 11, // Alias 27 | } 28 | 29 | 30 | /** 31 | * This helper function takes a string, number or anything that can 32 | * be used in the constructor of a Money object, and returns a bigint 33 | * with adjusted precision. 34 | */ 35 | export function moneyValueToBigInt(input: Money | string | number | bigint, round: Round): bigint { 36 | 37 | if (input instanceof Money) { 38 | return input.toSource(); 39 | } 40 | 41 | switch (typeof input) { 42 | case 'string' : { 43 | 44 | const parts = input.match(/^(-)?([0-9]*)?(\.([0-9]*))?$/); 45 | 46 | if (!parts) { 47 | throw new TypeError('Input string must follow the pattern (-)##.## or -##'); 48 | } 49 | 50 | const signPart: '-'|undefined = parts[1] as ('-' | undefined); // Positive or negative 51 | const wholePart: string|undefined = parts[2]; // Whole numbers. 52 | const fracPart: string|undefined = parts[4]; 53 | 54 | let output: bigint; 55 | // The whole part 56 | if (wholePart === undefined) { 57 | // For numbers like ".04" this part will be undefined. 58 | output = 0n; 59 | } else { 60 | output = BigInt(wholePart) * PRECISION_M; 61 | } 62 | 63 | if (fracPart !== undefined) { 64 | // The fractional part 65 | const precisionDifference: bigint = (PRECISION - BigInt(fracPart.length)); 66 | 67 | if (precisionDifference >= 0) { 68 | // Add 0's 69 | output += BigInt(fracPart) * 10n ** precisionDifference; 70 | } else { 71 | // Remove 0's 72 | output += divide(BigInt(fracPart), 10n ** (-precisionDifference), round); 73 | } 74 | } 75 | 76 | // negative ? 77 | if (signPart === '-') { 78 | output *= -1n; 79 | } 80 | return output; 81 | } 82 | case 'bigint': 83 | return input * PRECISION_M; 84 | case 'number' : 85 | if (!Number.isSafeInteger(input)) { 86 | throw new UnsafeIntegerError('The number ' + input + ' is not a "safe" integer. It must be converted before passing it'); 87 | } 88 | return BigInt(input) * PRECISION_M; 89 | default : 90 | throw new TypeError('value must be a safe integer, bigint or string'); 91 | 92 | } 93 | 94 | } 95 | 96 | /** 97 | * This function takes a bigint that was multiplied by PRECISON_M, and returns 98 | * a human readable string value with a specified precision. 99 | * 100 | * Precision is the number of decimals that are returned. 101 | */ 102 | export function bigintToFixed(value: bigint, precision: number, round: Round) { 103 | 104 | if (precision === 0) { 105 | // No decimals were requested. 106 | return divide(value, PRECISION_M, round).toString(); 107 | } 108 | 109 | let wholePart = (value / PRECISION_M); 110 | const negative = value < 0; 111 | let remainder = (value % PRECISION_M); 112 | 113 | if (precision > PRECISION) { 114 | // More precision was requested than we have, so we multiply 115 | // to add more 0's 116 | remainder *= 10n ** (BigInt(precision) - PRECISION); 117 | } else { 118 | // Less precision was requested, so we round 119 | remainder = divide(remainder, 10n ** (PRECISION - BigInt(precision)), round); 120 | } 121 | 122 | if (remainder < 0) { remainder *= -1n; } 123 | 124 | let remainderStr = remainder.toString().padStart(precision, '0'); 125 | 126 | if (remainderStr.length > precision) { 127 | // The remainder rounded all the way up to the the 'whole part' 128 | wholePart += negative ? -1n : 1n; 129 | remainder = 0n; 130 | remainderStr = '0'.repeat(precision); 131 | } 132 | 133 | let wholePartStr = wholePart.toString(); 134 | if (wholePartStr === '0' && negative) { 135 | wholePartStr = '-0'; 136 | } 137 | 138 | return wholePartStr + '.' + remainderStr; 139 | } 140 | 141 | /** 142 | * This function takes 2 bigints and divides them. 143 | * 144 | * By default ecmascript will round to 0. For example, 145 | * 5n / 2n yields 2n. 146 | * 147 | * This function rounds to the nearest even number, also 148 | * known as 'bankers rounding'. 149 | */ 150 | export function divide(a: bigint, b: bigint, round: Round) { 151 | 152 | // Get absolute versions. We'll deal with the negatives later. 153 | const aAbs = a > 0 ? a : -a; 154 | const bAbs = b > 0 ? b : -b; 155 | 156 | let result = aAbs / bAbs; 157 | const rem = aAbs % bAbs; 158 | 159 | // if remainder > half divisor 160 | if (rem * 2n > bAbs) { 161 | switch (round) { 162 | case Round.TRUNCATE: 163 | // do nothing 164 | break; 165 | default : 166 | // We should have rounded up instead of down. 167 | result++; 168 | break; 169 | } 170 | } else if (rem * 2n === bAbs) { 171 | // If the remainder is exactly half the divisor, it means that the result is 172 | // exactly in between two numbers and we need to apply a specific rounding 173 | // method. 174 | switch (round) { 175 | case Round.HALF_TO_EVEN: 176 | // Add 1 if result is odd to get an even return value 177 | if (result % 2n === 1n) { result++; } 178 | break; 179 | case Round.HALF_AWAY_FROM_0: 180 | result++; 181 | break; 182 | case Round.TRUNCATE: 183 | case Round.HALF_TOWARDS_0: 184 | // Do nothing 185 | break; 186 | } 187 | } 188 | 189 | if (a > 0 !== b > 0) { 190 | // Either a XOR b is negative 191 | return -result; 192 | } else { 193 | return result; 194 | } 195 | 196 | } 197 | -------------------------------------------------------------------------------- /test/money-compare.ts: -------------------------------------------------------------------------------- 1 | import { Money, IncompatibleCurrencyError } from '../src/index.js'; 2 | import { describe, it } from 'node:test'; 3 | import assert from 'node:assert'; 4 | 5 | describe('Money.compare', () => { 6 | 7 | const cases = [ 8 | ['1', '2', -1], 9 | ['-10', '-20', 1], 10 | ['1', 1, 0], 11 | ['-100', '100', -1], 12 | ['-0', 0, 0], 13 | ['1.00000001', '1.00000002', -1], 14 | ['1.00000003', '1.00000002', 1], 15 | ]; 16 | 17 | for (const cas of cases) { 18 | 19 | let op; 20 | switch(cas[2]) { 21 | case -1: 22 | op = '<'; 23 | break; 24 | case 0 : 25 | op = '==='; 26 | break; 27 | case 1: 28 | op = '>'; 29 | break; 30 | } 31 | it(`${cas[0]} ${op} ${cas[1]} === true`, () => { 32 | 33 | const x = new Money(cas[0], 'AUD'); 34 | assert.equal( 35 | x.compare(cas[1]), 36 | cas[2] 37 | ); 38 | 39 | }); 40 | 41 | } 42 | 43 | it('should fail when using incompatible currencies', () => { 44 | 45 | const x = new Money(1, 'AUD'); 46 | const y = new Money(2, 'NZD'); 47 | assert.throws( 48 | () => x.compare(y), 49 | IncompatibleCurrencyError 50 | ); 51 | 52 | }); 53 | 54 | }); 55 | 56 | describe('Money.isLesserThan', () => { 57 | 58 | const cases:any = [ 59 | ['1', '2', true], 60 | ['-10', '-20', false], 61 | ['1', 1, false], 62 | ['-100', '100', true], 63 | ['-0', 0, false], 64 | ['1.00000001', '1.00000002', true], 65 | ['1.00000003', '1.00000002', false], 66 | ]; 67 | 68 | for (const cas of cases) { 69 | 70 | it(`${cas[0]}.isLesserThan(${cas[1]}) === true`, () => { 71 | 72 | const x = new Money(cas[0], 'AUD'); 73 | assert.equal( 74 | x.isLesserThan(cas[1]), 75 | cas[2] 76 | ); 77 | 78 | }); 79 | 80 | } 81 | 82 | }); 83 | 84 | describe('Money.isGreaterThan', () => { 85 | 86 | const cases:any = [ 87 | ['1', '2', false], 88 | ['-10', '-20', true], 89 | ['1', 1, false], 90 | ['-100', '100', false], 91 | ['-0', 0, false], 92 | ['1.00000001', '1.00000002', false], 93 | ['1.00000003', '1.00000002', true], 94 | ]; 95 | 96 | for (const cas of cases) { 97 | 98 | it(`${cas[0]}.isGreaterThan(${cas[1]}) === true`, () => { 99 | 100 | const x = new Money(cas[0], 'AUD'); 101 | assert.equal( 102 | x.isGreaterThan(cas[1]), 103 | cas[2] 104 | ); 105 | 106 | }); 107 | 108 | } 109 | 110 | }); 111 | 112 | describe('Money.isEqual', () => { 113 | 114 | const cases:any = [ 115 | ['1', '2', false], 116 | ['-10', '-20', false], 117 | ['1', 1, true], 118 | ['-100', '100', false], 119 | ['-0', 0, true], 120 | ['1.00000001', '1.00000002', false], 121 | ['1.00000003', '1.00000002', false], 122 | ]; 123 | 124 | for (const cas of cases) { 125 | 126 | it(`${cas[0]}.isEqual(${cas[1]}) === true`, () => { 127 | 128 | const x = new Money(cas[0], 'AUD'); 129 | assert.equal( 130 | x.isEqual(cas[1]), 131 | cas[2] 132 | ); 133 | 134 | }); 135 | 136 | } 137 | 138 | }); 139 | 140 | describe('Money.isLesserThanOrEqual', () => { 141 | 142 | const cases:any = [ 143 | ['1', '2', true], 144 | ['-10', '-20', false], 145 | ['1', 1, true], 146 | ['-100', '100', true], 147 | ['-0', 0, true], 148 | ['1.00000001', '1.00000002', true], 149 | ['1.00000003', '1.00000002', false], 150 | ]; 151 | 152 | for (const cas of cases) { 153 | 154 | it(`${cas[0]}.isLesserThanOrEqual(${cas[1]}) === true`, () => { 155 | 156 | const x = new Money(cas[0], 'AUD'); 157 | assert.equal( 158 | x.isLesserThanOrEqual(cas[1]), 159 | cas[2] 160 | ); 161 | 162 | }); 163 | 164 | } 165 | 166 | }); 167 | 168 | describe('Money.isGreaterThanOrEqual', () => { 169 | 170 | const cases:any = [ 171 | ['1', '2', false], 172 | ['-10', '-20', true], 173 | ['1', 1, true], 174 | ['-100', '100', false], 175 | ['-0', 0, true], 176 | ['1.00000001', '1.00000002', false], 177 | ['1.00000003', '1.00000002', true], 178 | ]; 179 | 180 | for (const cas of cases) { 181 | 182 | it(`${cas[0]}.isGreaterThanOrEqual(${cas[1]}) === true`, () => { 183 | 184 | const x = new Money(cas[0], 'AUD'); 185 | assert.equal( 186 | x.isGreaterThanOrEqual(cas[1]), 187 | cas[2] 188 | ); 189 | }); 190 | 191 | } 192 | 193 | }); 194 | -------------------------------------------------------------------------------- /test/money.ts: -------------------------------------------------------------------------------- 1 | import { Money, UnsafeIntegerError, IncompatibleCurrencyError } from '../src/index.js'; 2 | import { PRECISION_I } from '../src/util'; 3 | import { describe, it } from 'node:test'; 4 | import assert from 'node:assert'; 5 | 6 | describe('Money class', () => { 7 | 8 | it('should instantiate', () => { 9 | 10 | const m = new Money(1, 'USD'); 11 | assert.ok(m instanceof Money); 12 | assert.equal(m.currency, 'USD'); 13 | 14 | }); 15 | 16 | it('should error when instantiating with inprecise numbers', () => { 17 | 18 | assert.throws( 19 | () => new Money(1.1, 'yen'), 20 | UnsafeIntegerError 21 | ); 22 | 23 | }); 24 | 25 | it('should error when instantiating with bad string formats', () => { 26 | 27 | assert.throws( 28 | () => new Money('1,5', 'yen'), 29 | TypeError, 30 | ); 31 | 32 | }); 33 | 34 | describe('toFixed', () => { 35 | 36 | const tests: [any, number, string][] = [ 37 | [1, 3, '1.000'], 38 | 39 | ['3.5', 0, '4'], 40 | ['-3.5', 0, '-4'], 41 | ['2.5', 0, '2'], 42 | ['-2.5', 0, '-2'], 43 | 44 | ['.35', 1, '0.4'], 45 | ['-.35', 1, '-0.4'], 46 | ['.25', 1, '0.2'], 47 | ['-.25', 1, '-0.2'], 48 | 49 | 50 | [1, 15, '1.' + ('0'.repeat(15))], 51 | ['1.555', 15, '1.555' + ('0'.repeat(12))], 52 | ['1.00555', 15, '1.00555' + ('0'.repeat(10))], 53 | 54 | ]; 55 | 56 | for(const test of tests) { 57 | it(`should return ${test[2]} when calling toFixed on ${test[0]} with ${test[1]} precision`, () => { 58 | 59 | assert.equal( 60 | new Money(test[0], 'USD').toFixed(test[1]), 61 | test[2] 62 | ); 63 | 64 | }); 65 | } 66 | 67 | }); 68 | describe('format', () => { 69 | 70 | const tests = [ 71 | [1, '1'], 72 | 73 | ['1.005', '1.005'], 74 | ['1.0000', '1'], 75 | ['-12314.325400050500', '-12314.3254000505'], 76 | ['-5.0000', '-5'], 77 | 78 | ]; 79 | 80 | for(const test of tests) { 81 | it(`should return ${test[1]} when calling format on ${test[0]}`, () => { 82 | 83 | const m = new Money(test[0], 'USD'); 84 | assert.equal(m.format(), test[1]); 85 | 86 | }); 87 | } 88 | 89 | }); 90 | 91 | describe('Numbers with more precision than '+PRECISION_I+' digits', () => { 92 | 93 | const zeroes = '0'.repeat(PRECISION_I-1); 94 | 95 | it('should round to even', () => { 96 | 97 | const m = new Money('1.' + zeroes + '05', 'USD'); 98 | assert.ok(m instanceof Money); 99 | assert.equal(m.currency, 'USD'); 100 | assert.equal( 101 | m.toFixed(PRECISION_I + 1), 102 | '1.' + zeroes + '00' 103 | ); 104 | }); 105 | 106 | it('should round to even (2)', () => { 107 | 108 | const m = new Money('1.' + zeroes + '15', 'USD'); 109 | assert.ok(m instanceof Money); 110 | assert.equal(m.currency,'USD'); 111 | assert.equal( 112 | m.toFixed(PRECISION_I + 1), 113 | '1.' + zeroes + '20' 114 | ); 115 | 116 | }); 117 | 118 | }); 119 | 120 | describe('add', () => { 121 | 122 | it('should return a new Money object with the added number', () => { 123 | 124 | const x = new Money(1, 'USD'); 125 | const y = new Money(2, 'USD'); 126 | const z = y.add(x); 127 | 128 | assert.equal( 129 | z.toFixed(3), 130 | '3.000' 131 | ); 132 | 133 | }); 134 | 135 | it('should work with non-money objects', () => { 136 | 137 | const x = 1; 138 | const y = new Money(2, 'USD'); 139 | const z = y.add(x); 140 | 141 | assert.equal( 142 | z.toFixed(3), 143 | '3.000' 144 | ); 145 | 146 | }); 147 | 148 | it('should error when using different currencies', () => { 149 | 150 | const x = new Money(1, 'USD'); 151 | const y = new Money(2, 'YEN'); 152 | 153 | assert.throws( 154 | () => y.add(x), 155 | IncompatibleCurrencyError 156 | ); 157 | 158 | }); 159 | 160 | const cases: [string|number, string|number, string][] = [ 161 | ['0.1', '0.2', '0.30'], 162 | ['0.3', '-0.2', '0.10'], 163 | [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, '18014398509481982.00'], 164 | 165 | ['17.954', '.001', '17.96'], 166 | 167 | ['0.002', '0.003', '0.00'], 168 | ['0.012', '0.003', '0.02'], 169 | ]; 170 | 171 | for(const cas of cases) { 172 | 173 | it(`${cas[0]} + ${cas[1]} = ${cas[2]}`, () => { 174 | 175 | const x = new Money(cas[0], 'USD'); 176 | const y = new Money(cas[1], 'USD'); 177 | 178 | assert.equal( 179 | x.add(y).toFixed(2), 180 | cas[2] 181 | ); 182 | 183 | }); 184 | 185 | } 186 | 187 | }); 188 | 189 | describe('subtract', () => { 190 | 191 | it('should return a new Money object with the subtracted number', () => { 192 | 193 | const x = new Money(1, 'USD'); 194 | const y = new Money(2, 'USD'); 195 | const z = x.subtract(y); 196 | 197 | assert.equal( 198 | z.toFixed(3), 199 | '-1.000' 200 | ); 201 | 202 | }); 203 | 204 | it('should work with non-money objects', () => { 205 | 206 | const x = 3; 207 | const y = new Money(2, 'USD'); 208 | const z = y.subtract(x); 209 | 210 | assert.equal( 211 | z.toFixed(3), 212 | '-1.000' 213 | ); 214 | 215 | }); 216 | 217 | it('should error when using different currencies', () => { 218 | 219 | const x = new Money(1, 'USD'); 220 | const y = new Money(2, 'YEN'); 221 | 222 | assert.throws( 223 | () => y.subtract(x), 224 | IncompatibleCurrencyError 225 | ); 226 | 227 | }); 228 | 229 | const cases = [ 230 | ['0.1', '0.2', '-0.10'], 231 | ['0.3', '-0.2', '0.50'], 232 | // These are larger than MAX_SAFE_INT 233 | ['9007199254740992.555555555','9007199254740992.555555555', '0.00'], 234 | ]; 235 | 236 | for(const cas of cases) { 237 | 238 | it(`${cas[0]} + ${cas[1]} = ${cas[2]}`, () => { 239 | 240 | const x = new Money(cas[0], 'USD'); 241 | const y = new Money(cas[1], 'USD'); 242 | 243 | assert.equal( 244 | x.subtract(y).toFixed(2), 245 | cas[2] 246 | ); 247 | 248 | }); 249 | 250 | } 251 | 252 | 253 | }); 254 | 255 | describe('divide', () => { 256 | 257 | const cases = [ 258 | ['1', '3', '0.33'], 259 | ['-1' , '3', '-0.33'], 260 | ['1', '-3', '-0.33'], 261 | ['-1', '-3', '0.33'], 262 | 263 | ['0.3', '3', '0.10'], 264 | ['-0.3', '3', '-0.10'], 265 | ['0.3', '-3', '-0.10'], 266 | ['-0.3', '-3', '0.10'], 267 | 268 | // Round half even (down) 269 | ['3.015', '3', '1.00'], 270 | ['-3.015', '3', '-1.00'], 271 | ['3.015', '-3', '-1.00'], 272 | ['-3.015', '-3', '1.00'], 273 | 274 | // Round half to even (up) 275 | ['3.045', '3', '1.02'], 276 | ['-3.045', '3', '-1.02'], 277 | ['3.045', '-3', '-1.02'], 278 | ['-3.045', '-3', '1.02'], 279 | 280 | 281 | ]; 282 | 283 | for (const cas of cases) { 284 | 285 | it(`${cas[0]} / ${cas[1]} = ${cas[2]}`, () => { 286 | 287 | const x = new Money(cas[0], 'ETH'); 288 | assert.equal( 289 | x.divide(cas[1]).toFixed(2), 290 | cas[2] 291 | ); 292 | 293 | }); 294 | 295 | } 296 | 297 | }); 298 | 299 | describe('multiply', () => { 300 | 301 | const cases = [ 302 | ['1', '3', '3.00'], 303 | ['10000', 20, '200000.00'], 304 | [20, 5, '100.00'], 305 | [-20, 5, '-100.00'], 306 | [-20, -5, '100.00'], 307 | [20, -5, '-100.00'], 308 | ['0.5', '0.2', '0.10'], 309 | ['-0.5', '0.2', '-0.10'], 310 | ['-0.5', '-0.2', '0.10'], 311 | ['0.5', '-0.2', '-0.10'], 312 | ]; 313 | 314 | for (const cas of cases) { 315 | 316 | it(`${cas[0]} * ${cas[1]} = ${cas[2]}`, () => { 317 | 318 | const x = new Money(cas[0], 'ETH'); 319 | assert.equal( 320 | x.multiply(cas[1]).toFixed(2), 321 | cas[2] 322 | ); 323 | 324 | }); 325 | 326 | } 327 | 328 | }); 329 | 330 | describe('pow', () => { 331 | 332 | const cases: [string|number, number, string][] = [ 333 | ['1', 5,'1.00'], 334 | ['2', 8, '256.00'], 335 | [5, 3, '125.00'], 336 | [-10, 5, '-100000.00'], 337 | [-10, 1, '-10.00'], 338 | [-10, 0, '1.00'], 339 | [2, -2, '0.25'], 340 | ]; 341 | 342 | for (const cas of cases) { 343 | 344 | it(`${cas[0]} ** ${cas[1]} = ${cas[2]}`, () => { 345 | 346 | const x = new Money(cas[0], 'CAD'); 347 | assert.equal(x.pow(cas[1]).toFixed(2),cas[2]); 348 | 349 | }); 350 | 351 | } 352 | 353 | }); 354 | 355 | describe('abs', () => { 356 | 357 | const cases = [ 358 | ['0', '0.00'], 359 | ['-1', '1.00'], 360 | ['-10000', '10000.00'], 361 | [20, '20.00'], 362 | [-20, '20.00'], 363 | ['0.5', '0.50'], 364 | ['-0.5', '0.50'], 365 | ]; 366 | 367 | for (const cas of cases) { 368 | 369 | it(`abs(${cas[0]}) = ${cas[1]}`, () => { 370 | 371 | const x = new Money(cas[0], 'ETH'); 372 | assert.equal(x.abs().toFixed(2), cas[1]); 373 | 374 | }); 375 | 376 | } 377 | 378 | }); 379 | 380 | describe('sign', () => { 381 | 382 | const cases = [ 383 | ['0', 0], 384 | ['-1', -1], 385 | ['-10000', -1], 386 | [20, 1], 387 | [-20, -1], 388 | ['0.5', 1], 389 | ['-0.5', -1], 390 | ]; 391 | 392 | for (const cas of cases) { 393 | 394 | it(`sign(${cas[0]}) = ${cas[1]}`, () => { 395 | 396 | const x = new Money(cas[0], 'ETH'); 397 | assert.equal(x.sign(), cas[1]); 398 | 399 | }); 400 | 401 | } 402 | 403 | }); 404 | 405 | describe('allocate', () => { 406 | 407 | const cases:any = [ 408 | ['1', 3, 2, ['0.34', '0.33', '0.33']], 409 | ['-10', 7, 2, ['-1.43', '-1.43', '-1.43', '-1.43', '-1.43', '-1.43', '-1.42']], 410 | ]; 411 | 412 | for(const cas of cases) { 413 | it(`splitting $${cas[0]} between ${cas[1]} people should result in ${(cas[3]).join(', ')}`, () => { 414 | 415 | const x = new Money(cas[0], 'CAD'); 416 | const result = x.allocate(cas[1], cas[2]); 417 | 418 | assert.deepEqual( 419 | result.map( 420 | item => item.toFixed(cas[2]) 421 | ), 422 | cas[3] 423 | ); 424 | 425 | // Double-check. Numbers must exactly add up to the source value 426 | assert.deepEqual( 427 | result.reduce( 428 | (acc, cur) => acc + cur.toSource(), 0n 429 | ), 430 | x.toSource() 431 | ); 432 | 433 | }); 434 | 435 | } 436 | }); 437 | 438 | describe('toSource', () => { 439 | 440 | it('should return the underlying source bigint value', () => { 441 | 442 | const m = new Money(1, 'USD'); 443 | assert.equal( 444 | m.toSource(), 445 | 1n * (10n ** BigInt(PRECISION_I)) 446 | ); 447 | 448 | }); 449 | 450 | }); 451 | 452 | describe('Debug output', () => { 453 | 454 | it('should return a meaningful value', () => { 455 | 456 | const m = new Money(1, 'USD'); 457 | 458 | assert.equal( 459 | (m as any)[Symbol.for('nodejs.util.inspect.custom')](), 460 | '1 USD' 461 | ); 462 | 463 | }); 464 | 465 | }); 466 | 467 | describe('toJSON', () => { 468 | 469 | const cases = [ 470 | ['1.000', '["1","DKK"]'], 471 | ['1.100', '["1.1","DKK"]'], 472 | ['1.111', '["1.111","DKK"]'], 473 | ['10.11', '["10.11","DKK"]'], 474 | ['10.00', '["10","DKK"]'], 475 | ]; 476 | 477 | for(const cas of cases) { 478 | 479 | it(`${cas[0]} DKK should JSON stringify to ${cas[1]}`, () => { 480 | 481 | const m = new Money(cas[0], 'DKK'); 482 | const result = JSON.stringify(m); 483 | assert.equal(result, cas[1]); 484 | 485 | }); 486 | 487 | } 488 | 489 | }); 490 | 491 | }); 492 | -------------------------------------------------------------------------------- /test/util-bigint-to-fixed.ts: -------------------------------------------------------------------------------- 1 | import { bigintToFixed, Round, PRECISION } from '../src/util.js'; 2 | import { describe, it } from 'node:test'; 3 | import assert from 'node:assert'; 4 | 5 | describe('bigintToFixed', () => { 6 | 7 | const P = PRECISION; 8 | 9 | const tests = [ 10 | [ 1n, 0, '0'], 11 | [ 1n * (10n ** P), 0, '1'], 12 | [ 1n * (10n ** (P-1n)), 0, '0'], 13 | [ 1n * (10n ** (P-1n)), 1, '0.1'], 14 | [ 1n * (10n ** (P-2n)), 2, '0.01'], 15 | [ 4n * (10n ** (P-3n)), 2, '0.00'], 16 | [ 5n * (10n ** (P-3n)), 2, '0.00'], 17 | [ 6n * (10n ** (P-3n)), 2, '0.01'], 18 | [ 99n * (10n ** (P-2n)), 2, '0.99'], 19 | [ 995n * (10n ** (P-3n)), 2, '1.00'], 20 | [ -1n, 0, '0'], 21 | [ -1n * (10n ** P), 0, '-1'], 22 | [ -1n * (10n ** (P-1n)), 0, '0'], 23 | [ -1n * (10n ** (P-1n)), 1, '-0.1'], 24 | [ -1n * (10n ** (P-2n)), 2, '-0.01'], 25 | [ -4n * (10n ** (P-3n)), 2, '-0.00'], 26 | [ -5n * (10n ** (P-3n)), 2, '-0.00'], 27 | [ -6n * (10n ** (P-3n)), 2, '-0.01'], 28 | [ -99n * (10n ** (P-2n)), 2, '-0.99'], 29 | [-995n * (10n ** (P-3n)), 2, '-1.00'], 30 | ]; 31 | 32 | for(const test of tests) { 33 | it(`bigintToFixed(${test[0]},${test[1]}) === ${test[2]}`, () => { 34 | 35 | const result = bigintToFixed(test[0] as bigint, test[1] as number, Round.BANKERS); 36 | assert.equal( 37 | result, 38 | test[2] 39 | ); 40 | 41 | }); 42 | } 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /test/util-rounding.ts: -------------------------------------------------------------------------------- 1 | import { divide, Round } from '../src/util.js'; 2 | import { describe, it } from 'node:test'; 3 | import assert from 'node:assert'; 4 | 5 | describe('divide', () => { 6 | 7 | describe('HALF_TO_EVEN', () => { 8 | const tests = [ 9 | 10 | // .5 cases 11 | [7n, 2n, 4n], 12 | [5n, 2n, 2n], 13 | [-7n, 2n, -4n], 14 | [-5n, 2n, -2n], 15 | 16 | // Common cases 17 | [8n, 3n, 3n], 18 | [9n, 4n, 2n], 19 | [-9n, 4n, -2n], 20 | ]; 21 | 22 | for(const test of tests) { 23 | 24 | it(`${test[0]} / ${test[1]} = ${test[2]}`, () => { 25 | 26 | assert.equal( 27 | divide(test[0], test[1], Round.HALF_TO_EVEN), 28 | test[2] 29 | ); 30 | 31 | }); 32 | 33 | } 34 | 35 | }); 36 | 37 | describe('HALF_AWAY_FROM_0', () => { 38 | const tests = [ 39 | 40 | // .5 cases 41 | [7n, 2n, 4n], 42 | [5n, 2n, 3n], 43 | [-7n, 2n, -4n], 44 | [-5n, 2n, -3n], 45 | 46 | // Common cases 47 | [8n, 3n, 3n], 48 | [9n, 4n, 2n], 49 | [-9n, 4n, -2n], 50 | ]; 51 | 52 | for(const test of tests) { 53 | 54 | it(`${test[0]} / ${test[1]} = ${test[2]}`, () => { 55 | 56 | assert.equal( 57 | divide(test[0], test[1], Round.HALF_AWAY_FROM_0), 58 | test[2] 59 | ); 60 | 61 | }); 62 | 63 | } 64 | 65 | }); 66 | 67 | describe('HALF_TOWARDS_0', () => { 68 | const tests = [ 69 | 70 | // .5 cases 71 | [7n, 2n, 3n], 72 | [5n, 2n, 2n], 73 | [-7n, 2n, -3n], 74 | [-5n, 2n, -2n], 75 | 76 | // Common cases 77 | [8n, 3n, 3n], 78 | [9n, 4n, 2n], 79 | [-9n, 4n, -2n], 80 | ]; 81 | 82 | for(const test of tests) { 83 | 84 | it(`${test[0]} / ${test[1]} = ${test[2]}`, () => { 85 | 86 | assert.equal( 87 | divide(test[0], test[1], Round.HALF_TOWARDS_0), 88 | test[2] 89 | ); 90 | 91 | }); 92 | 93 | } 94 | 95 | }); 96 | 97 | describe('TRUNCATE', () => { 98 | const tests = [ 99 | 100 | // .5 cases 101 | [7n, 2n, 3n], 102 | [5n, 2n, 2n], 103 | [-7n, 2n, -3n], 104 | [-5n, 2n, -2n], 105 | 106 | // Common cases 107 | [8n, 3n, 2n], 108 | [9n, 4n, 2n], 109 | [-8n, 3n, -2n], 110 | [-9n, 4n, -2n], 111 | ]; 112 | 113 | for(const test of tests) { 114 | 115 | it(`${test[0]} / ${test[1]} = ${test[2]}`, () => { 116 | 117 | assert.equal( 118 | divide(test[0], test[1], Round.TRUNCATE), 119 | test[2], 120 | ); 121 | 122 | }); 123 | 124 | } 125 | 126 | }); 127 | 128 | }); 129 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "target": "es2022", 5 | "strict": true, 6 | 7 | "sourceMap": true, 8 | "outDir": "dist", 9 | "baseUrl": ".", 10 | "paths": { 11 | "*": [ 12 | "src/types/*" 13 | ] 14 | }, 15 | "lib": [ 16 | "DOM", 17 | "ES2018", 18 | "ESNext.bigint" 19 | ], 20 | 21 | "declaration": true 22 | }, 23 | "include": [ 24 | "src/**/*" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------