├── .github └── workflows │ ├── nodejs.yml │ └── publish.yml ├── .gitignore ├── .npmrc ├── LICENSE ├── README.md ├── bench └── benchmark.cjs ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── src ├── index.ts ├── types.ts └── utils.ts ├── tests ├── balance.test.ts ├── compare.test.ts ├── contains.test.ts ├── duplicate.test.ts ├── empty.test.ts ├── find.test.ts ├── insert.test.ts ├── keys-values.test.ts ├── min-max.test.ts ├── remove.test.ts └── traversal.test.ts ├── tsconfig.json └── vite.config.ts /.github/workflows/nodejs.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: [master] 9 | pull_request: 10 | branches: [master] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [18.x, 20.x] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Use Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v1 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | - run: npm ci 27 | - run: npm run build --if-present 28 | - run: npm test 29 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - "v*.*.*" 5 | 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 20 15 | - run: npm ci 16 | - run: npm run build 17 | - run: npm test 18 | - uses: JS-DevTools/npm-publish@v1 19 | with: 20 | token: ${{ secrets.NPM_TOKEN }} 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | dist 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Alexander Milevski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AVL tree [![npm version](https://badge.fury.io/js/avl.svg)](https://badge.fury.io/js/avl) 2 | 3 | [AVL-tree](https://en.wikipedia.org/wiki/AVL_tree): **[fast](#benchmarks)**(non-recursive) and **simple**(< 500 lines of code) 4 | 5 | ![AVL-tree](https://upload.wikimedia.org/wikipedia/commons/a/ad/AVL-tree-wBalance_K.svg) 6 | 7 | | Operation | Average | Worst case | 8 | | ------------- | ------------- | ------------ | 9 | | Space | **O(n)** | **O(n)** | 10 | | Search | **O(log n)** | **O(log n)** | 11 | | Insert | **O(log n)** | **O(log n)** | 12 | | Delete | **O(log n)** | **O(log n)** | 13 | 14 | 15 | ## Install 16 | 17 | ```shell 18 | npm i -S avl 19 | ``` 20 | 21 | ```js 22 | import AVLTree from 'avl'; 23 | const tree = new AVLTree(); 24 | ``` 25 | 26 | Or get it from CDN 27 | ```html 28 | 29 | 33 | ``` 34 | Or use the compiled version 'dist/avl.js'. 35 | 36 | [Try it in your browser](https://npm.runkit.com/avl) 37 | 38 | ## API 39 | 40 | * `new AVLTree([comparator], [noDuplicates:Boolean])`, where `compare` is optional comparison function 41 | * `tree.insert(key:any, [data:any])` - Insert item 42 | * `tree.remove(key:any)` - Remove item 43 | * `tree.find(key):Node|Null` - Return node by its key 44 | * `tree.at(index:Number):Node|Null` - Return node by its index in sorted order of keys 45 | * `tree.contains(key):Boolean` - Whether a node with the given key is in the tree 46 | * `tree.forEach(function(node) {...}):Tree` In-order traversal 47 | * `tree.range(lo, high, function(node) {} [, context]):Tree` - Walks the range of keys in order. Stops, if the visitor function returns a non-zero value. 48 | * `tree.keys():Array` - Returns the array of keys in order 49 | * `tree.values():Array<*>` - Returns the array of data fields in order 50 | * `tree.pop():Node` - Removes smallest node 51 | * `tree.popMax():Node` - Removes highest node 52 | * `tree.min():key` - Returns min key 53 | * `tree.max():key` - Returns max key 54 | * `tree.minNode():Node` - Returns the node with smallest key 55 | * `tree.maxNode():Node` - Returns the node with highest key 56 | * `tree.prev(node):Node` - Predecessor node 57 | * `tree.next(node):Node` - Successor node 58 | * `tree.load(keys:Array<*>, [values:Array<*>], presort = false):Tree` - Bulk-load items 59 | * `tree.destroy():Tree, tree.clear():Tree` - Empty the tree 60 | 61 | **Comparator** 62 | 63 | `function(a:key,b:key):Number` - Comparator function between two keys, it returns 64 | * `0` if the keys are equal 65 | * `<0` if `a < b` 66 | * `>0` if `a > b` 67 | 68 | The comparator function is extremely important, in case of errors you might end 69 | up with a wrongly constructed tree or would not be able to retrieve your items. 70 | It is crucial to test the return values of your `comparator(a,b)` and `comparator(b,a)` 71 | to make sure it's working correctly, otherwise you may have bugs that are very 72 | unpredictable and hard to catch. 73 | 74 | **Duplicate keys** 75 | 76 | By default, tree allows duplicate keys. You can disable that by passing `true` 77 | as a second parameter to the tree constructor. In that case if you would try to 78 | instert an item with the key, that is already present in the tree, it will not 79 | be inserted. 80 | However, the default behavior allows for duplicate keys, cause there are cases 81 | where you cannot predict that the keys would be unique (example: overlapping 82 | points in 2D). 83 | 84 | ## Example 85 | 86 | ```js 87 | import Tree from 'avl'; 88 | 89 | const t = new Tree(); 90 | t.insert(5); 91 | t.insert(-10); 92 | t.insert(0); 93 | t.insert(33); 94 | t.insert(2); 95 | 96 | console.log(t.keys()); // [-10, 0, 2, 5, 33] 97 | console.log(t.size); // 5 98 | console.log(t.min()); // -10 99 | console.log(t.max()); // 33 100 | 101 | t.remove(0); 102 | console.log(t.size); // 4 103 | ``` 104 | 105 | **Custom comparator (reverse sort)** 106 | 107 | ```js 108 | import Tree from 'avl'; 109 | 110 | const t = new Tree((a, b) => b - a); 111 | t.insert(5); 112 | t.insert(-10); 113 | t.insert(0); 114 | t.insert(33); 115 | t.insert(2); 116 | 117 | console.log(t.keys()); // [33, 5, 2, 0, -10] 118 | ``` 119 | 120 | **Bulk insert** 121 | 122 | ```js 123 | import Tree from 'avl'; 124 | 125 | const t = new Tree(); 126 | t.load([3,2,-10,20], ['C', 'B', 'A', 'D'], true); 127 | console.log(t.keys()); // [-10, 2, 3, 20] 128 | console.log(t.values()); // ['A', 'B', 'C', 'D'] 129 | ``` 130 | 131 | ## Benchmarks 132 | 133 | ```shell 134 | npm run benchmark 135 | ``` 136 | 137 | ``` 138 | Insert (x1000) 139 | Bintrees x 3,742 ops/sec ±0.89% (90 runs sampled) 140 | Functional red black tree x 1,880 ops/sec ±4.02% (78 runs sampled) 141 | Google Closure library AVL x 622 ops/sec ±4.22% (81 runs sampled) 142 | AVL (current) x 6,151 ops/sec ±8.50% (72 runs sampled) 143 | - Fastest is AVL (current) 144 | 145 | Random read (x1000) 146 | Bintrees x 7,371 ops/sec ±2.69% (83 runs sampled) 147 | Functional red black tree x 13,010 ops/sec ±2.93% (83 runs sampled) 148 | Google Closure library AVL x 27.63 ops/sec ±1.04% (49 runs sampled) 149 | AVL (current) x 12,921 ops/sec ±1.83% (86 runs sampled) 150 | - Fastest is AVL (current) 151 | 152 | Remove (x1000) 153 | Bintrees x 106,837 ops/sec ±0.74% (86 runs sampled) 154 | Functional red black tree x 25,368 ops/sec ±0.89% (88 runs sampled) 155 | Google Closure library AVL x 31,719 ops/sec ±1.21% (89 runs sampled) 156 | AVL (current) x 108,131 ops/sec ±0.70% (88 runs sampled) 157 | - Fastest is AVL (current) 158 | ``` 159 | 160 | Adding google closure library to the benchmark is, of course, unfair, cause the 161 | node.js version of it is not optimised by the compiler, but in this case it 162 | plays the role of straight-forward robust implementation. 163 | 164 | ## Develop 165 | 166 | ```shell 167 | npm i 168 | npm t 169 | npm run build 170 | ``` 171 | 172 | ## License 173 | 174 | The MIT License (MIT) 175 | 176 | Copyright (c) 2017 Alexander Milevski 177 | 178 | Permission is hereby granted, free of charge, to any person obtaining a copy of 179 | this software and associated documentation files (the "Software"), to deal in 180 | the Software without restriction, including without limitation the rights to 181 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 182 | the Software, and to permit persons to whom the Software is furnished to do so, 183 | subject to the following conditions: 184 | 185 | The above copyright notice and this permission notice shall be included in all 186 | copies or substantial portions of the Software. 187 | 188 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 189 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 190 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 191 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 192 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 193 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 194 | -------------------------------------------------------------------------------- /bench/benchmark.cjs: -------------------------------------------------------------------------------- 1 | const Benchmark = require("benchmark"); 2 | const { AVLTree: Tree } = require("../dist/index.cjs"); 3 | const FRB = require("functional-red-black-tree"); 4 | const { RBTree } = require("bintrees"); 5 | 6 | // eslint-disable-next-line @typescript-eslint/no-require-imports 7 | require("google-closure-library"); 8 | goog.require("goog.structs.AvlTree"); 9 | 10 | const N = 1000; 11 | const rvalues = new Array(N).fill(0).map(() => Math.floor(Math.random() * N)); 12 | const values = new Array(N).fill(0).map((_, i) => i); 13 | 14 | const prefilledAVL = new Tree(); 15 | rvalues.forEach((v) => prefilledAVL.insert(v)); 16 | 17 | const prefilledRB = new RBTree((a, b) => a - b); 18 | rvalues.forEach((v) => prefilledRB.insert(v)); 19 | 20 | let prefilledFRB = new FRB(); 21 | rvalues.forEach((v) => { 22 | prefilledFRB = prefilledFRB.insert(v); 23 | }); 24 | 25 | const prefilledGCAVL = new goog.structs.AvlTree((a, b) => a - b); 26 | rvalues.forEach((v) => prefilledGCAVL.add(v)); 27 | 28 | const options = { 29 | onStart() { 30 | console.log(this.name); 31 | }, 32 | onError(event) { 33 | console.log(event.target.error); 34 | }, 35 | onCycle(event) { 36 | console.log(String(event.target)); 37 | }, 38 | onComplete() { 39 | console.log("- Fastest is " + this.filter("fastest").map("name") + "\n"); 40 | }, 41 | }; 42 | 43 | new Benchmark.Suite(`Insert (x${N})`, options) 44 | .add("Bintrees", () => { 45 | let rb = new RBTree((a, b) => a - b); 46 | for (let i = 0; i < N; i++) rb.insert(rvalues[i]); 47 | }) 48 | .add("Functional red black tree", () => { 49 | let frb = new FRB(); 50 | for (let i = 0; i < N; i++) frb = frb.insert(rvalues[i]); 51 | }) 52 | .add("Google Closure library AVL", () => { 53 | let gcavl = new goog.structs.AvlTree((a, b) => a - b); 54 | for (let i = 0; i < N; i++) gcavl.add(rvalues[i]); 55 | }) 56 | .add("AVL (current)", () => { 57 | const tree = new Tree(); 58 | for (let i = 0; i < N; i++) tree.insert(rvalues[i]); 59 | }) 60 | .run(); 61 | 62 | new Benchmark.Suite(`Random read (x${N})`, options) 63 | .add("Bintrees", () => { 64 | for (let i = N - 1; i; i--) prefilledRB.find(rvalues[i]); 65 | }) 66 | .add("Functional red black tree", () => { 67 | for (let i = N - 1; i; i--) prefilledFRB.get(rvalues[i]); 68 | }) 69 | .add("Google Closure library AVL", () => { 70 | for (let i = 0; i < N; i++) 71 | prefilledGCAVL.inOrderTraverse((v) => v === rvalues[i]); 72 | }) 73 | .add("AVL (current)", () => { 74 | for (let i = 0; i < N; i++) prefilledAVL.find(rvalues[i]); 75 | }) 76 | .run(); 77 | 78 | new Benchmark.Suite(`Remove (x${N})`, options) 79 | .add("Bintrees", () => { 80 | for (let i = 0; i < N; i++) prefilledRB.remove(rvalues[i]); 81 | }) 82 | .add("Functional red black tree", () => { 83 | for (let i = 0; i < N; i++) prefilledFRB = prefilledFRB.remove(rvalues[i]); 84 | }) 85 | .add("Google Closure library AVL", () => { 86 | for (let i = 0; i < N; i++) prefilledGCAVL.remove(rvalues[i]); 87 | }) 88 | .add("AVL (current)", () => { 89 | for (let i = N - 1; i; i--) prefilledAVL.remove(values[i]); 90 | }) 91 | .run(); 92 | 93 | const M = 10000; 94 | const arr = new Array(M).fill(0).map(() => M * Math.random()); 95 | arr.sort((a, b) => a - b); 96 | new Benchmark.Suite(`Bulk-load (x${M})`, options) 97 | .add("1 by 1", () => { 98 | const t = new Tree(); 99 | for (let i = 0; i < M; i++) t.insert(arr[i]); 100 | }) 101 | .add("bulk load", () => { 102 | const t = new Tree(); 103 | const data = arr.slice(); 104 | 105 | t.load(data, []); 106 | }) 107 | .run(); 108 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import globals from "globals"; 2 | import tseslint from "typescript-eslint"; 3 | 4 | /** @type {import('eslint').Linter.Config[]} */ 5 | export default [ 6 | { files: ["src/**/*.ts", "tests/**/*.test.ts"], ignores: ["dist"] }, 7 | { languageOptions: { globals: { ...globals.browser, ...globals.node } } }, 8 | ...tseslint.configs.recommended, 9 | ]; 10 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avl", 3 | "version": "1.6.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "avl", 9 | "version": "1.6.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@types/bintrees": "^1.0.6", 13 | "benchmark": "^2.1.4", 14 | "bintrees": "^1.0.2", 15 | "dts-bundle-generator": "^9.5.1", 16 | "eslint": "^9.21.0", 17 | "functional-red-black-tree": "^1.0.1", 18 | "globals": "^16.0.0", 19 | "google-closure-library": "^20210406.0.0", 20 | "typescript-eslint": "^8.25.0", 21 | "vite": "^6.2.0", 22 | "vitest": "^3.0.7" 23 | } 24 | }, 25 | "node_modules/@esbuild/aix-ppc64": { 26 | "version": "0.25.0", 27 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", 28 | "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", 29 | "cpu": [ 30 | "ppc64" 31 | ], 32 | "dev": true, 33 | "license": "MIT", 34 | "optional": true, 35 | "os": [ 36 | "aix" 37 | ], 38 | "engines": { 39 | "node": ">=18" 40 | } 41 | }, 42 | "node_modules/@esbuild/android-arm": { 43 | "version": "0.25.0", 44 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", 45 | "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", 46 | "cpu": [ 47 | "arm" 48 | ], 49 | "dev": true, 50 | "license": "MIT", 51 | "optional": true, 52 | "os": [ 53 | "android" 54 | ], 55 | "engines": { 56 | "node": ">=18" 57 | } 58 | }, 59 | "node_modules/@esbuild/android-arm64": { 60 | "version": "0.25.0", 61 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", 62 | "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", 63 | "cpu": [ 64 | "arm64" 65 | ], 66 | "dev": true, 67 | "license": "MIT", 68 | "optional": true, 69 | "os": [ 70 | "android" 71 | ], 72 | "engines": { 73 | "node": ">=18" 74 | } 75 | }, 76 | "node_modules/@esbuild/android-x64": { 77 | "version": "0.25.0", 78 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", 79 | "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", 80 | "cpu": [ 81 | "x64" 82 | ], 83 | "dev": true, 84 | "license": "MIT", 85 | "optional": true, 86 | "os": [ 87 | "android" 88 | ], 89 | "engines": { 90 | "node": ">=18" 91 | } 92 | }, 93 | "node_modules/@esbuild/darwin-arm64": { 94 | "version": "0.25.0", 95 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", 96 | "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", 97 | "cpu": [ 98 | "arm64" 99 | ], 100 | "dev": true, 101 | "license": "MIT", 102 | "optional": true, 103 | "os": [ 104 | "darwin" 105 | ], 106 | "engines": { 107 | "node": ">=18" 108 | } 109 | }, 110 | "node_modules/@esbuild/darwin-x64": { 111 | "version": "0.25.0", 112 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", 113 | "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", 114 | "cpu": [ 115 | "x64" 116 | ], 117 | "dev": true, 118 | "license": "MIT", 119 | "optional": true, 120 | "os": [ 121 | "darwin" 122 | ], 123 | "engines": { 124 | "node": ">=18" 125 | } 126 | }, 127 | "node_modules/@esbuild/freebsd-arm64": { 128 | "version": "0.25.0", 129 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", 130 | "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", 131 | "cpu": [ 132 | "arm64" 133 | ], 134 | "dev": true, 135 | "license": "MIT", 136 | "optional": true, 137 | "os": [ 138 | "freebsd" 139 | ], 140 | "engines": { 141 | "node": ">=18" 142 | } 143 | }, 144 | "node_modules/@esbuild/freebsd-x64": { 145 | "version": "0.25.0", 146 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", 147 | "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", 148 | "cpu": [ 149 | "x64" 150 | ], 151 | "dev": true, 152 | "license": "MIT", 153 | "optional": true, 154 | "os": [ 155 | "freebsd" 156 | ], 157 | "engines": { 158 | "node": ">=18" 159 | } 160 | }, 161 | "node_modules/@esbuild/linux-arm": { 162 | "version": "0.25.0", 163 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", 164 | "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", 165 | "cpu": [ 166 | "arm" 167 | ], 168 | "dev": true, 169 | "license": "MIT", 170 | "optional": true, 171 | "os": [ 172 | "linux" 173 | ], 174 | "engines": { 175 | "node": ">=18" 176 | } 177 | }, 178 | "node_modules/@esbuild/linux-arm64": { 179 | "version": "0.25.0", 180 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", 181 | "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", 182 | "cpu": [ 183 | "arm64" 184 | ], 185 | "dev": true, 186 | "license": "MIT", 187 | "optional": true, 188 | "os": [ 189 | "linux" 190 | ], 191 | "engines": { 192 | "node": ">=18" 193 | } 194 | }, 195 | "node_modules/@esbuild/linux-ia32": { 196 | "version": "0.25.0", 197 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", 198 | "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", 199 | "cpu": [ 200 | "ia32" 201 | ], 202 | "dev": true, 203 | "license": "MIT", 204 | "optional": true, 205 | "os": [ 206 | "linux" 207 | ], 208 | "engines": { 209 | "node": ">=18" 210 | } 211 | }, 212 | "node_modules/@esbuild/linux-loong64": { 213 | "version": "0.25.0", 214 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", 215 | "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", 216 | "cpu": [ 217 | "loong64" 218 | ], 219 | "dev": true, 220 | "license": "MIT", 221 | "optional": true, 222 | "os": [ 223 | "linux" 224 | ], 225 | "engines": { 226 | "node": ">=18" 227 | } 228 | }, 229 | "node_modules/@esbuild/linux-mips64el": { 230 | "version": "0.25.0", 231 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", 232 | "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", 233 | "cpu": [ 234 | "mips64el" 235 | ], 236 | "dev": true, 237 | "license": "MIT", 238 | "optional": true, 239 | "os": [ 240 | "linux" 241 | ], 242 | "engines": { 243 | "node": ">=18" 244 | } 245 | }, 246 | "node_modules/@esbuild/linux-ppc64": { 247 | "version": "0.25.0", 248 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", 249 | "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", 250 | "cpu": [ 251 | "ppc64" 252 | ], 253 | "dev": true, 254 | "license": "MIT", 255 | "optional": true, 256 | "os": [ 257 | "linux" 258 | ], 259 | "engines": { 260 | "node": ">=18" 261 | } 262 | }, 263 | "node_modules/@esbuild/linux-riscv64": { 264 | "version": "0.25.0", 265 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", 266 | "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", 267 | "cpu": [ 268 | "riscv64" 269 | ], 270 | "dev": true, 271 | "license": "MIT", 272 | "optional": true, 273 | "os": [ 274 | "linux" 275 | ], 276 | "engines": { 277 | "node": ">=18" 278 | } 279 | }, 280 | "node_modules/@esbuild/linux-s390x": { 281 | "version": "0.25.0", 282 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", 283 | "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", 284 | "cpu": [ 285 | "s390x" 286 | ], 287 | "dev": true, 288 | "license": "MIT", 289 | "optional": true, 290 | "os": [ 291 | "linux" 292 | ], 293 | "engines": { 294 | "node": ">=18" 295 | } 296 | }, 297 | "node_modules/@esbuild/linux-x64": { 298 | "version": "0.25.0", 299 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", 300 | "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", 301 | "cpu": [ 302 | "x64" 303 | ], 304 | "dev": true, 305 | "license": "MIT", 306 | "optional": true, 307 | "os": [ 308 | "linux" 309 | ], 310 | "engines": { 311 | "node": ">=18" 312 | } 313 | }, 314 | "node_modules/@esbuild/netbsd-arm64": { 315 | "version": "0.25.0", 316 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", 317 | "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", 318 | "cpu": [ 319 | "arm64" 320 | ], 321 | "dev": true, 322 | "license": "MIT", 323 | "optional": true, 324 | "os": [ 325 | "netbsd" 326 | ], 327 | "engines": { 328 | "node": ">=18" 329 | } 330 | }, 331 | "node_modules/@esbuild/netbsd-x64": { 332 | "version": "0.25.0", 333 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", 334 | "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", 335 | "cpu": [ 336 | "x64" 337 | ], 338 | "dev": true, 339 | "license": "MIT", 340 | "optional": true, 341 | "os": [ 342 | "netbsd" 343 | ], 344 | "engines": { 345 | "node": ">=18" 346 | } 347 | }, 348 | "node_modules/@esbuild/openbsd-arm64": { 349 | "version": "0.25.0", 350 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", 351 | "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", 352 | "cpu": [ 353 | "arm64" 354 | ], 355 | "dev": true, 356 | "license": "MIT", 357 | "optional": true, 358 | "os": [ 359 | "openbsd" 360 | ], 361 | "engines": { 362 | "node": ">=18" 363 | } 364 | }, 365 | "node_modules/@esbuild/openbsd-x64": { 366 | "version": "0.25.0", 367 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", 368 | "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", 369 | "cpu": [ 370 | "x64" 371 | ], 372 | "dev": true, 373 | "license": "MIT", 374 | "optional": true, 375 | "os": [ 376 | "openbsd" 377 | ], 378 | "engines": { 379 | "node": ">=18" 380 | } 381 | }, 382 | "node_modules/@esbuild/sunos-x64": { 383 | "version": "0.25.0", 384 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", 385 | "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", 386 | "cpu": [ 387 | "x64" 388 | ], 389 | "dev": true, 390 | "license": "MIT", 391 | "optional": true, 392 | "os": [ 393 | "sunos" 394 | ], 395 | "engines": { 396 | "node": ">=18" 397 | } 398 | }, 399 | "node_modules/@esbuild/win32-arm64": { 400 | "version": "0.25.0", 401 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", 402 | "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", 403 | "cpu": [ 404 | "arm64" 405 | ], 406 | "dev": true, 407 | "license": "MIT", 408 | "optional": true, 409 | "os": [ 410 | "win32" 411 | ], 412 | "engines": { 413 | "node": ">=18" 414 | } 415 | }, 416 | "node_modules/@esbuild/win32-ia32": { 417 | "version": "0.25.0", 418 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", 419 | "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", 420 | "cpu": [ 421 | "ia32" 422 | ], 423 | "dev": true, 424 | "license": "MIT", 425 | "optional": true, 426 | "os": [ 427 | "win32" 428 | ], 429 | "engines": { 430 | "node": ">=18" 431 | } 432 | }, 433 | "node_modules/@esbuild/win32-x64": { 434 | "version": "0.25.0", 435 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", 436 | "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", 437 | "cpu": [ 438 | "x64" 439 | ], 440 | "dev": true, 441 | "license": "MIT", 442 | "optional": true, 443 | "os": [ 444 | "win32" 445 | ], 446 | "engines": { 447 | "node": ">=18" 448 | } 449 | }, 450 | "node_modules/@eslint-community/eslint-utils": { 451 | "version": "4.4.1", 452 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", 453 | "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", 454 | "dev": true, 455 | "license": "MIT", 456 | "dependencies": { 457 | "eslint-visitor-keys": "^3.4.3" 458 | }, 459 | "engines": { 460 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 461 | }, 462 | "funding": { 463 | "url": "https://opencollective.com/eslint" 464 | }, 465 | "peerDependencies": { 466 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 467 | } 468 | }, 469 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 470 | "version": "3.4.3", 471 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 472 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 473 | "dev": true, 474 | "license": "Apache-2.0", 475 | "engines": { 476 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 477 | }, 478 | "funding": { 479 | "url": "https://opencollective.com/eslint" 480 | } 481 | }, 482 | "node_modules/@eslint-community/regexpp": { 483 | "version": "4.12.1", 484 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 485 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 486 | "dev": true, 487 | "license": "MIT", 488 | "engines": { 489 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 490 | } 491 | }, 492 | "node_modules/@eslint/config-array": { 493 | "version": "0.19.2", 494 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", 495 | "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", 496 | "dev": true, 497 | "license": "Apache-2.0", 498 | "dependencies": { 499 | "@eslint/object-schema": "^2.1.6", 500 | "debug": "^4.3.1", 501 | "minimatch": "^3.1.2" 502 | }, 503 | "engines": { 504 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 505 | } 506 | }, 507 | "node_modules/@eslint/core": { 508 | "version": "0.12.0", 509 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", 510 | "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", 511 | "dev": true, 512 | "license": "Apache-2.0", 513 | "dependencies": { 514 | "@types/json-schema": "^7.0.15" 515 | }, 516 | "engines": { 517 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 518 | } 519 | }, 520 | "node_modules/@eslint/eslintrc": { 521 | "version": "3.3.0", 522 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", 523 | "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", 524 | "dev": true, 525 | "license": "MIT", 526 | "dependencies": { 527 | "ajv": "^6.12.4", 528 | "debug": "^4.3.2", 529 | "espree": "^10.0.1", 530 | "globals": "^14.0.0", 531 | "ignore": "^5.2.0", 532 | "import-fresh": "^3.2.1", 533 | "js-yaml": "^4.1.0", 534 | "minimatch": "^3.1.2", 535 | "strip-json-comments": "^3.1.1" 536 | }, 537 | "engines": { 538 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 539 | }, 540 | "funding": { 541 | "url": "https://opencollective.com/eslint" 542 | } 543 | }, 544 | "node_modules/@eslint/eslintrc/node_modules/globals": { 545 | "version": "14.0.0", 546 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 547 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 548 | "dev": true, 549 | "license": "MIT", 550 | "engines": { 551 | "node": ">=18" 552 | }, 553 | "funding": { 554 | "url": "https://github.com/sponsors/sindresorhus" 555 | } 556 | }, 557 | "node_modules/@eslint/js": { 558 | "version": "9.21.0", 559 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", 560 | "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", 561 | "dev": true, 562 | "license": "MIT", 563 | "engines": { 564 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 565 | } 566 | }, 567 | "node_modules/@eslint/object-schema": { 568 | "version": "2.1.6", 569 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 570 | "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 571 | "dev": true, 572 | "license": "Apache-2.0", 573 | "engines": { 574 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 575 | } 576 | }, 577 | "node_modules/@eslint/plugin-kit": { 578 | "version": "0.2.7", 579 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", 580 | "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", 581 | "dev": true, 582 | "license": "Apache-2.0", 583 | "dependencies": { 584 | "@eslint/core": "^0.12.0", 585 | "levn": "^0.4.1" 586 | }, 587 | "engines": { 588 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 589 | } 590 | }, 591 | "node_modules/@humanfs/core": { 592 | "version": "0.19.1", 593 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 594 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 595 | "dev": true, 596 | "license": "Apache-2.0", 597 | "engines": { 598 | "node": ">=18.18.0" 599 | } 600 | }, 601 | "node_modules/@humanfs/node": { 602 | "version": "0.16.6", 603 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 604 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 605 | "dev": true, 606 | "license": "Apache-2.0", 607 | "dependencies": { 608 | "@humanfs/core": "^0.19.1", 609 | "@humanwhocodes/retry": "^0.3.0" 610 | }, 611 | "engines": { 612 | "node": ">=18.18.0" 613 | } 614 | }, 615 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 616 | "version": "0.3.1", 617 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 618 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 619 | "dev": true, 620 | "license": "Apache-2.0", 621 | "engines": { 622 | "node": ">=18.18" 623 | }, 624 | "funding": { 625 | "type": "github", 626 | "url": "https://github.com/sponsors/nzakas" 627 | } 628 | }, 629 | "node_modules/@humanwhocodes/module-importer": { 630 | "version": "1.0.1", 631 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 632 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 633 | "dev": true, 634 | "license": "Apache-2.0", 635 | "engines": { 636 | "node": ">=12.22" 637 | }, 638 | "funding": { 639 | "type": "github", 640 | "url": "https://github.com/sponsors/nzakas" 641 | } 642 | }, 643 | "node_modules/@humanwhocodes/retry": { 644 | "version": "0.4.2", 645 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", 646 | "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", 647 | "dev": true, 648 | "license": "Apache-2.0", 649 | "engines": { 650 | "node": ">=18.18" 651 | }, 652 | "funding": { 653 | "type": "github", 654 | "url": "https://github.com/sponsors/nzakas" 655 | } 656 | }, 657 | "node_modules/@jridgewell/sourcemap-codec": { 658 | "version": "1.5.0", 659 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 660 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 661 | "dev": true, 662 | "license": "MIT" 663 | }, 664 | "node_modules/@nodelib/fs.scandir": { 665 | "version": "2.1.5", 666 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 667 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 668 | "dev": true, 669 | "license": "MIT", 670 | "dependencies": { 671 | "@nodelib/fs.stat": "2.0.5", 672 | "run-parallel": "^1.1.9" 673 | }, 674 | "engines": { 675 | "node": ">= 8" 676 | } 677 | }, 678 | "node_modules/@nodelib/fs.stat": { 679 | "version": "2.0.5", 680 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 681 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 682 | "dev": true, 683 | "license": "MIT", 684 | "engines": { 685 | "node": ">= 8" 686 | } 687 | }, 688 | "node_modules/@nodelib/fs.walk": { 689 | "version": "1.2.8", 690 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 691 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 692 | "dev": true, 693 | "license": "MIT", 694 | "dependencies": { 695 | "@nodelib/fs.scandir": "2.1.5", 696 | "fastq": "^1.6.0" 697 | }, 698 | "engines": { 699 | "node": ">= 8" 700 | } 701 | }, 702 | "node_modules/@rollup/rollup-android-arm-eabi": { 703 | "version": "4.34.8", 704 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", 705 | "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", 706 | "cpu": [ 707 | "arm" 708 | ], 709 | "dev": true, 710 | "license": "MIT", 711 | "optional": true, 712 | "os": [ 713 | "android" 714 | ] 715 | }, 716 | "node_modules/@rollup/rollup-android-arm64": { 717 | "version": "4.34.8", 718 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", 719 | "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", 720 | "cpu": [ 721 | "arm64" 722 | ], 723 | "dev": true, 724 | "license": "MIT", 725 | "optional": true, 726 | "os": [ 727 | "android" 728 | ] 729 | }, 730 | "node_modules/@rollup/rollup-darwin-arm64": { 731 | "version": "4.34.8", 732 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", 733 | "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", 734 | "cpu": [ 735 | "arm64" 736 | ], 737 | "dev": true, 738 | "license": "MIT", 739 | "optional": true, 740 | "os": [ 741 | "darwin" 742 | ] 743 | }, 744 | "node_modules/@rollup/rollup-darwin-x64": { 745 | "version": "4.34.8", 746 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", 747 | "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", 748 | "cpu": [ 749 | "x64" 750 | ], 751 | "dev": true, 752 | "license": "MIT", 753 | "optional": true, 754 | "os": [ 755 | "darwin" 756 | ] 757 | }, 758 | "node_modules/@rollup/rollup-freebsd-arm64": { 759 | "version": "4.34.8", 760 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", 761 | "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", 762 | "cpu": [ 763 | "arm64" 764 | ], 765 | "dev": true, 766 | "license": "MIT", 767 | "optional": true, 768 | "os": [ 769 | "freebsd" 770 | ] 771 | }, 772 | "node_modules/@rollup/rollup-freebsd-x64": { 773 | "version": "4.34.8", 774 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", 775 | "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", 776 | "cpu": [ 777 | "x64" 778 | ], 779 | "dev": true, 780 | "license": "MIT", 781 | "optional": true, 782 | "os": [ 783 | "freebsd" 784 | ] 785 | }, 786 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 787 | "version": "4.34.8", 788 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", 789 | "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", 790 | "cpu": [ 791 | "arm" 792 | ], 793 | "dev": true, 794 | "license": "MIT", 795 | "optional": true, 796 | "os": [ 797 | "linux" 798 | ] 799 | }, 800 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 801 | "version": "4.34.8", 802 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", 803 | "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", 804 | "cpu": [ 805 | "arm" 806 | ], 807 | "dev": true, 808 | "license": "MIT", 809 | "optional": true, 810 | "os": [ 811 | "linux" 812 | ] 813 | }, 814 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 815 | "version": "4.34.8", 816 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", 817 | "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", 818 | "cpu": [ 819 | "arm64" 820 | ], 821 | "dev": true, 822 | "license": "MIT", 823 | "optional": true, 824 | "os": [ 825 | "linux" 826 | ] 827 | }, 828 | "node_modules/@rollup/rollup-linux-arm64-musl": { 829 | "version": "4.34.8", 830 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", 831 | "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", 832 | "cpu": [ 833 | "arm64" 834 | ], 835 | "dev": true, 836 | "license": "MIT", 837 | "optional": true, 838 | "os": [ 839 | "linux" 840 | ] 841 | }, 842 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 843 | "version": "4.34.8", 844 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", 845 | "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", 846 | "cpu": [ 847 | "loong64" 848 | ], 849 | "dev": true, 850 | "license": "MIT", 851 | "optional": true, 852 | "os": [ 853 | "linux" 854 | ] 855 | }, 856 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 857 | "version": "4.34.8", 858 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", 859 | "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", 860 | "cpu": [ 861 | "ppc64" 862 | ], 863 | "dev": true, 864 | "license": "MIT", 865 | "optional": true, 866 | "os": [ 867 | "linux" 868 | ] 869 | }, 870 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 871 | "version": "4.34.8", 872 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", 873 | "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", 874 | "cpu": [ 875 | "riscv64" 876 | ], 877 | "dev": true, 878 | "license": "MIT", 879 | "optional": true, 880 | "os": [ 881 | "linux" 882 | ] 883 | }, 884 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 885 | "version": "4.34.8", 886 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", 887 | "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", 888 | "cpu": [ 889 | "s390x" 890 | ], 891 | "dev": true, 892 | "license": "MIT", 893 | "optional": true, 894 | "os": [ 895 | "linux" 896 | ] 897 | }, 898 | "node_modules/@rollup/rollup-linux-x64-gnu": { 899 | "version": "4.34.8", 900 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", 901 | "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", 902 | "cpu": [ 903 | "x64" 904 | ], 905 | "dev": true, 906 | "license": "MIT", 907 | "optional": true, 908 | "os": [ 909 | "linux" 910 | ] 911 | }, 912 | "node_modules/@rollup/rollup-linux-x64-musl": { 913 | "version": "4.34.8", 914 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", 915 | "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", 916 | "cpu": [ 917 | "x64" 918 | ], 919 | "dev": true, 920 | "license": "MIT", 921 | "optional": true, 922 | "os": [ 923 | "linux" 924 | ] 925 | }, 926 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 927 | "version": "4.34.8", 928 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", 929 | "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", 930 | "cpu": [ 931 | "arm64" 932 | ], 933 | "dev": true, 934 | "license": "MIT", 935 | "optional": true, 936 | "os": [ 937 | "win32" 938 | ] 939 | }, 940 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 941 | "version": "4.34.8", 942 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", 943 | "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", 944 | "cpu": [ 945 | "ia32" 946 | ], 947 | "dev": true, 948 | "license": "MIT", 949 | "optional": true, 950 | "os": [ 951 | "win32" 952 | ] 953 | }, 954 | "node_modules/@rollup/rollup-win32-x64-msvc": { 955 | "version": "4.34.8", 956 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", 957 | "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", 958 | "cpu": [ 959 | "x64" 960 | ], 961 | "dev": true, 962 | "license": "MIT", 963 | "optional": true, 964 | "os": [ 965 | "win32" 966 | ] 967 | }, 968 | "node_modules/@types/bintrees": { 969 | "version": "1.0.6", 970 | "resolved": "https://registry.npmjs.org/@types/bintrees/-/bintrees-1.0.6.tgz", 971 | "integrity": "sha512-pZWT4Bz+tWwxlDspSjdoIza4PE5lbGI4Xvs3FZV/2v5m5SDA8LwNpU8AXxlndmARO7OaQ1Vf3zFenOsNMzaRkQ==", 972 | "dev": true, 973 | "license": "MIT" 974 | }, 975 | "node_modules/@types/estree": { 976 | "version": "1.0.6", 977 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 978 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 979 | "dev": true, 980 | "license": "MIT" 981 | }, 982 | "node_modules/@types/json-schema": { 983 | "version": "7.0.15", 984 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 985 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 986 | "dev": true, 987 | "license": "MIT" 988 | }, 989 | "node_modules/@types/node": { 990 | "version": "22.13.5", 991 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", 992 | "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", 993 | "dev": true, 994 | "license": "MIT", 995 | "optional": true, 996 | "peer": true, 997 | "dependencies": { 998 | "undici-types": "~6.20.0" 999 | } 1000 | }, 1001 | "node_modules/@typescript-eslint/eslint-plugin": { 1002 | "version": "8.25.0", 1003 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.25.0.tgz", 1004 | "integrity": "sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==", 1005 | "dev": true, 1006 | "license": "MIT", 1007 | "dependencies": { 1008 | "@eslint-community/regexpp": "^4.10.0", 1009 | "@typescript-eslint/scope-manager": "8.25.0", 1010 | "@typescript-eslint/type-utils": "8.25.0", 1011 | "@typescript-eslint/utils": "8.25.0", 1012 | "@typescript-eslint/visitor-keys": "8.25.0", 1013 | "graphemer": "^1.4.0", 1014 | "ignore": "^5.3.1", 1015 | "natural-compare": "^1.4.0", 1016 | "ts-api-utils": "^2.0.1" 1017 | }, 1018 | "engines": { 1019 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1020 | }, 1021 | "funding": { 1022 | "type": "opencollective", 1023 | "url": "https://opencollective.com/typescript-eslint" 1024 | }, 1025 | "peerDependencies": { 1026 | "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", 1027 | "eslint": "^8.57.0 || ^9.0.0", 1028 | "typescript": ">=4.8.4 <5.8.0" 1029 | } 1030 | }, 1031 | "node_modules/@typescript-eslint/parser": { 1032 | "version": "8.25.0", 1033 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.25.0.tgz", 1034 | "integrity": "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==", 1035 | "dev": true, 1036 | "license": "MIT", 1037 | "dependencies": { 1038 | "@typescript-eslint/scope-manager": "8.25.0", 1039 | "@typescript-eslint/types": "8.25.0", 1040 | "@typescript-eslint/typescript-estree": "8.25.0", 1041 | "@typescript-eslint/visitor-keys": "8.25.0", 1042 | "debug": "^4.3.4" 1043 | }, 1044 | "engines": { 1045 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1046 | }, 1047 | "funding": { 1048 | "type": "opencollective", 1049 | "url": "https://opencollective.com/typescript-eslint" 1050 | }, 1051 | "peerDependencies": { 1052 | "eslint": "^8.57.0 || ^9.0.0", 1053 | "typescript": ">=4.8.4 <5.8.0" 1054 | } 1055 | }, 1056 | "node_modules/@typescript-eslint/scope-manager": { 1057 | "version": "8.25.0", 1058 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.25.0.tgz", 1059 | "integrity": "sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==", 1060 | "dev": true, 1061 | "license": "MIT", 1062 | "dependencies": { 1063 | "@typescript-eslint/types": "8.25.0", 1064 | "@typescript-eslint/visitor-keys": "8.25.0" 1065 | }, 1066 | "engines": { 1067 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1068 | }, 1069 | "funding": { 1070 | "type": "opencollective", 1071 | "url": "https://opencollective.com/typescript-eslint" 1072 | } 1073 | }, 1074 | "node_modules/@typescript-eslint/type-utils": { 1075 | "version": "8.25.0", 1076 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.25.0.tgz", 1077 | "integrity": "sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==", 1078 | "dev": true, 1079 | "license": "MIT", 1080 | "dependencies": { 1081 | "@typescript-eslint/typescript-estree": "8.25.0", 1082 | "@typescript-eslint/utils": "8.25.0", 1083 | "debug": "^4.3.4", 1084 | "ts-api-utils": "^2.0.1" 1085 | }, 1086 | "engines": { 1087 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1088 | }, 1089 | "funding": { 1090 | "type": "opencollective", 1091 | "url": "https://opencollective.com/typescript-eslint" 1092 | }, 1093 | "peerDependencies": { 1094 | "eslint": "^8.57.0 || ^9.0.0", 1095 | "typescript": ">=4.8.4 <5.8.0" 1096 | } 1097 | }, 1098 | "node_modules/@typescript-eslint/types": { 1099 | "version": "8.25.0", 1100 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.25.0.tgz", 1101 | "integrity": "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==", 1102 | "dev": true, 1103 | "license": "MIT", 1104 | "engines": { 1105 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1106 | }, 1107 | "funding": { 1108 | "type": "opencollective", 1109 | "url": "https://opencollective.com/typescript-eslint" 1110 | } 1111 | }, 1112 | "node_modules/@typescript-eslint/typescript-estree": { 1113 | "version": "8.25.0", 1114 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.25.0.tgz", 1115 | "integrity": "sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==", 1116 | "dev": true, 1117 | "license": "MIT", 1118 | "dependencies": { 1119 | "@typescript-eslint/types": "8.25.0", 1120 | "@typescript-eslint/visitor-keys": "8.25.0", 1121 | "debug": "^4.3.4", 1122 | "fast-glob": "^3.3.2", 1123 | "is-glob": "^4.0.3", 1124 | "minimatch": "^9.0.4", 1125 | "semver": "^7.6.0", 1126 | "ts-api-utils": "^2.0.1" 1127 | }, 1128 | "engines": { 1129 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1130 | }, 1131 | "funding": { 1132 | "type": "opencollective", 1133 | "url": "https://opencollective.com/typescript-eslint" 1134 | }, 1135 | "peerDependencies": { 1136 | "typescript": ">=4.8.4 <5.8.0" 1137 | } 1138 | }, 1139 | "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 1140 | "version": "2.0.1", 1141 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1142 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1143 | "dev": true, 1144 | "license": "MIT", 1145 | "dependencies": { 1146 | "balanced-match": "^1.0.0" 1147 | } 1148 | }, 1149 | "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 1150 | "version": "9.0.5", 1151 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1152 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1153 | "dev": true, 1154 | "license": "ISC", 1155 | "dependencies": { 1156 | "brace-expansion": "^2.0.1" 1157 | }, 1158 | "engines": { 1159 | "node": ">=16 || 14 >=14.17" 1160 | }, 1161 | "funding": { 1162 | "url": "https://github.com/sponsors/isaacs" 1163 | } 1164 | }, 1165 | "node_modules/@typescript-eslint/utils": { 1166 | "version": "8.25.0", 1167 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.25.0.tgz", 1168 | "integrity": "sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==", 1169 | "dev": true, 1170 | "license": "MIT", 1171 | "dependencies": { 1172 | "@eslint-community/eslint-utils": "^4.4.0", 1173 | "@typescript-eslint/scope-manager": "8.25.0", 1174 | "@typescript-eslint/types": "8.25.0", 1175 | "@typescript-eslint/typescript-estree": "8.25.0" 1176 | }, 1177 | "engines": { 1178 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1179 | }, 1180 | "funding": { 1181 | "type": "opencollective", 1182 | "url": "https://opencollective.com/typescript-eslint" 1183 | }, 1184 | "peerDependencies": { 1185 | "eslint": "^8.57.0 || ^9.0.0", 1186 | "typescript": ">=4.8.4 <5.8.0" 1187 | } 1188 | }, 1189 | "node_modules/@typescript-eslint/visitor-keys": { 1190 | "version": "8.25.0", 1191 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.25.0.tgz", 1192 | "integrity": "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==", 1193 | "dev": true, 1194 | "license": "MIT", 1195 | "dependencies": { 1196 | "@typescript-eslint/types": "8.25.0", 1197 | "eslint-visitor-keys": "^4.2.0" 1198 | }, 1199 | "engines": { 1200 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1201 | }, 1202 | "funding": { 1203 | "type": "opencollective", 1204 | "url": "https://opencollective.com/typescript-eslint" 1205 | } 1206 | }, 1207 | "node_modules/@vitest/expect": { 1208 | "version": "3.0.7", 1209 | "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.7.tgz", 1210 | "integrity": "sha512-QP25f+YJhzPfHrHfYHtvRn+uvkCFCqFtW9CktfBxmB+25QqWsx7VB2As6f4GmwllHLDhXNHvqedwhvMmSnNmjw==", 1211 | "dev": true, 1212 | "license": "MIT", 1213 | "dependencies": { 1214 | "@vitest/spy": "3.0.7", 1215 | "@vitest/utils": "3.0.7", 1216 | "chai": "^5.2.0", 1217 | "tinyrainbow": "^2.0.0" 1218 | }, 1219 | "funding": { 1220 | "url": "https://opencollective.com/vitest" 1221 | } 1222 | }, 1223 | "node_modules/@vitest/mocker": { 1224 | "version": "3.0.7", 1225 | "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.7.tgz", 1226 | "integrity": "sha512-qui+3BLz9Eonx4EAuR/i+QlCX6AUZ35taDQgwGkK/Tw6/WgwodSrjN1X2xf69IA/643ZX5zNKIn2svvtZDrs4w==", 1227 | "dev": true, 1228 | "license": "MIT", 1229 | "dependencies": { 1230 | "@vitest/spy": "3.0.7", 1231 | "estree-walker": "^3.0.3", 1232 | "magic-string": "^0.30.17" 1233 | }, 1234 | "funding": { 1235 | "url": "https://opencollective.com/vitest" 1236 | }, 1237 | "peerDependencies": { 1238 | "msw": "^2.4.9", 1239 | "vite": "^5.0.0 || ^6.0.0" 1240 | }, 1241 | "peerDependenciesMeta": { 1242 | "msw": { 1243 | "optional": true 1244 | }, 1245 | "vite": { 1246 | "optional": true 1247 | } 1248 | } 1249 | }, 1250 | "node_modules/@vitest/mocker/node_modules/estree-walker": { 1251 | "version": "3.0.3", 1252 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 1253 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 1254 | "dev": true, 1255 | "license": "MIT", 1256 | "dependencies": { 1257 | "@types/estree": "^1.0.0" 1258 | } 1259 | }, 1260 | "node_modules/@vitest/pretty-format": { 1261 | "version": "3.0.7", 1262 | "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.7.tgz", 1263 | "integrity": "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg==", 1264 | "dev": true, 1265 | "license": "MIT", 1266 | "dependencies": { 1267 | "tinyrainbow": "^2.0.0" 1268 | }, 1269 | "funding": { 1270 | "url": "https://opencollective.com/vitest" 1271 | } 1272 | }, 1273 | "node_modules/@vitest/runner": { 1274 | "version": "3.0.7", 1275 | "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.7.tgz", 1276 | "integrity": "sha512-WeEl38Z0S2ZcuRTeyYqaZtm4e26tq6ZFqh5y8YD9YxfWuu0OFiGFUbnxNynwLjNRHPsXyee2M9tV7YxOTPZl2g==", 1277 | "dev": true, 1278 | "license": "MIT", 1279 | "dependencies": { 1280 | "@vitest/utils": "3.0.7", 1281 | "pathe": "^2.0.3" 1282 | }, 1283 | "funding": { 1284 | "url": "https://opencollective.com/vitest" 1285 | } 1286 | }, 1287 | "node_modules/@vitest/snapshot": { 1288 | "version": "3.0.7", 1289 | "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.7.tgz", 1290 | "integrity": "sha512-eqTUryJWQN0Rtf5yqCGTQWsCFOQe4eNz5Twsu21xYEcnFJtMU5XvmG0vgebhdLlrHQTSq5p8vWHJIeJQV8ovsA==", 1291 | "dev": true, 1292 | "license": "MIT", 1293 | "dependencies": { 1294 | "@vitest/pretty-format": "3.0.7", 1295 | "magic-string": "^0.30.17", 1296 | "pathe": "^2.0.3" 1297 | }, 1298 | "funding": { 1299 | "url": "https://opencollective.com/vitest" 1300 | } 1301 | }, 1302 | "node_modules/@vitest/spy": { 1303 | "version": "3.0.7", 1304 | "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.7.tgz", 1305 | "integrity": "sha512-4T4WcsibB0B6hrKdAZTM37ekuyFZt2cGbEGd2+L0P8ov15J1/HUsUaqkXEQPNAWr4BtPPe1gI+FYfMHhEKfR8w==", 1306 | "dev": true, 1307 | "license": "MIT", 1308 | "dependencies": { 1309 | "tinyspy": "^3.0.2" 1310 | }, 1311 | "funding": { 1312 | "url": "https://opencollective.com/vitest" 1313 | } 1314 | }, 1315 | "node_modules/@vitest/utils": { 1316 | "version": "3.0.7", 1317 | "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.7.tgz", 1318 | "integrity": "sha512-xePVpCRfooFX3rANQjwoditoXgWb1MaFbzmGuPP59MK6i13mrnDw/yEIyJudLeW6/38mCNcwCiJIGmpDPibAIg==", 1319 | "dev": true, 1320 | "license": "MIT", 1321 | "dependencies": { 1322 | "@vitest/pretty-format": "3.0.7", 1323 | "loupe": "^3.1.3", 1324 | "tinyrainbow": "^2.0.0" 1325 | }, 1326 | "funding": { 1327 | "url": "https://opencollective.com/vitest" 1328 | } 1329 | }, 1330 | "node_modules/acorn": { 1331 | "version": "8.14.0", 1332 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 1333 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 1334 | "dev": true, 1335 | "license": "MIT", 1336 | "bin": { 1337 | "acorn": "bin/acorn" 1338 | }, 1339 | "engines": { 1340 | "node": ">=0.4.0" 1341 | } 1342 | }, 1343 | "node_modules/acorn-jsx": { 1344 | "version": "5.3.2", 1345 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 1346 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 1347 | "dev": true, 1348 | "license": "MIT", 1349 | "peerDependencies": { 1350 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 1351 | } 1352 | }, 1353 | "node_modules/ajv": { 1354 | "version": "6.12.6", 1355 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1356 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1357 | "dev": true, 1358 | "license": "MIT", 1359 | "dependencies": { 1360 | "fast-deep-equal": "^3.1.1", 1361 | "fast-json-stable-stringify": "^2.0.0", 1362 | "json-schema-traverse": "^0.4.1", 1363 | "uri-js": "^4.2.2" 1364 | }, 1365 | "funding": { 1366 | "type": "github", 1367 | "url": "https://github.com/sponsors/epoberezkin" 1368 | } 1369 | }, 1370 | "node_modules/ansi-regex": { 1371 | "version": "5.0.1", 1372 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1373 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1374 | "dev": true, 1375 | "license": "MIT", 1376 | "engines": { 1377 | "node": ">=8" 1378 | } 1379 | }, 1380 | "node_modules/ansi-styles": { 1381 | "version": "4.3.0", 1382 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1383 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1384 | "dev": true, 1385 | "license": "MIT", 1386 | "dependencies": { 1387 | "color-convert": "^2.0.1" 1388 | }, 1389 | "engines": { 1390 | "node": ">=8" 1391 | }, 1392 | "funding": { 1393 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1394 | } 1395 | }, 1396 | "node_modules/argparse": { 1397 | "version": "2.0.1", 1398 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1399 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1400 | "dev": true, 1401 | "license": "Python-2.0" 1402 | }, 1403 | "node_modules/assertion-error": { 1404 | "version": "2.0.1", 1405 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", 1406 | "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", 1407 | "dev": true, 1408 | "license": "MIT", 1409 | "engines": { 1410 | "node": ">=12" 1411 | } 1412 | }, 1413 | "node_modules/balanced-match": { 1414 | "version": "1.0.2", 1415 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1416 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1417 | "dev": true, 1418 | "license": "MIT" 1419 | }, 1420 | "node_modules/benchmark": { 1421 | "version": "2.1.4", 1422 | "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", 1423 | "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", 1424 | "dev": true, 1425 | "license": "MIT", 1426 | "dependencies": { 1427 | "lodash": "^4.17.4", 1428 | "platform": "^1.3.3" 1429 | } 1430 | }, 1431 | "node_modules/bintrees": { 1432 | "version": "1.0.2", 1433 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", 1434 | "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==", 1435 | "dev": true, 1436 | "license": "MIT" 1437 | }, 1438 | "node_modules/brace-expansion": { 1439 | "version": "1.1.11", 1440 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1441 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1442 | "dev": true, 1443 | "license": "MIT", 1444 | "dependencies": { 1445 | "balanced-match": "^1.0.0", 1446 | "concat-map": "0.0.1" 1447 | } 1448 | }, 1449 | "node_modules/braces": { 1450 | "version": "3.0.3", 1451 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 1452 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 1453 | "dev": true, 1454 | "license": "MIT", 1455 | "dependencies": { 1456 | "fill-range": "^7.1.1" 1457 | }, 1458 | "engines": { 1459 | "node": ">=8" 1460 | } 1461 | }, 1462 | "node_modules/cac": { 1463 | "version": "6.7.14", 1464 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", 1465 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", 1466 | "dev": true, 1467 | "license": "MIT", 1468 | "engines": { 1469 | "node": ">=8" 1470 | } 1471 | }, 1472 | "node_modules/callsites": { 1473 | "version": "3.1.0", 1474 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 1475 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1476 | "dev": true, 1477 | "license": "MIT", 1478 | "engines": { 1479 | "node": ">=6" 1480 | } 1481 | }, 1482 | "node_modules/chai": { 1483 | "version": "5.2.0", 1484 | "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", 1485 | "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", 1486 | "dev": true, 1487 | "license": "MIT", 1488 | "dependencies": { 1489 | "assertion-error": "^2.0.1", 1490 | "check-error": "^2.1.1", 1491 | "deep-eql": "^5.0.1", 1492 | "loupe": "^3.1.0", 1493 | "pathval": "^2.0.0" 1494 | }, 1495 | "engines": { 1496 | "node": ">=12" 1497 | } 1498 | }, 1499 | "node_modules/chalk": { 1500 | "version": "4.1.2", 1501 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1502 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1503 | "dev": true, 1504 | "license": "MIT", 1505 | "dependencies": { 1506 | "ansi-styles": "^4.1.0", 1507 | "supports-color": "^7.1.0" 1508 | }, 1509 | "engines": { 1510 | "node": ">=10" 1511 | }, 1512 | "funding": { 1513 | "url": "https://github.com/chalk/chalk?sponsor=1" 1514 | } 1515 | }, 1516 | "node_modules/check-error": { 1517 | "version": "2.1.1", 1518 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", 1519 | "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", 1520 | "dev": true, 1521 | "license": "MIT", 1522 | "engines": { 1523 | "node": ">= 16" 1524 | } 1525 | }, 1526 | "node_modules/cliui": { 1527 | "version": "8.0.1", 1528 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 1529 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 1530 | "dev": true, 1531 | "license": "ISC", 1532 | "dependencies": { 1533 | "string-width": "^4.2.0", 1534 | "strip-ansi": "^6.0.1", 1535 | "wrap-ansi": "^7.0.0" 1536 | }, 1537 | "engines": { 1538 | "node": ">=12" 1539 | } 1540 | }, 1541 | "node_modules/color-convert": { 1542 | "version": "2.0.1", 1543 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1544 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1545 | "dev": true, 1546 | "license": "MIT", 1547 | "dependencies": { 1548 | "color-name": "~1.1.4" 1549 | }, 1550 | "engines": { 1551 | "node": ">=7.0.0" 1552 | } 1553 | }, 1554 | "node_modules/color-name": { 1555 | "version": "1.1.4", 1556 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1557 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1558 | "dev": true, 1559 | "license": "MIT" 1560 | }, 1561 | "node_modules/concat-map": { 1562 | "version": "0.0.1", 1563 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1564 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1565 | "dev": true, 1566 | "license": "MIT" 1567 | }, 1568 | "node_modules/cross-spawn": { 1569 | "version": "7.0.6", 1570 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 1571 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 1572 | "dev": true, 1573 | "license": "MIT", 1574 | "dependencies": { 1575 | "path-key": "^3.1.0", 1576 | "shebang-command": "^2.0.0", 1577 | "which": "^2.0.1" 1578 | }, 1579 | "engines": { 1580 | "node": ">= 8" 1581 | } 1582 | }, 1583 | "node_modules/debug": { 1584 | "version": "4.4.0", 1585 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1586 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1587 | "dev": true, 1588 | "license": "MIT", 1589 | "dependencies": { 1590 | "ms": "^2.1.3" 1591 | }, 1592 | "engines": { 1593 | "node": ">=6.0" 1594 | }, 1595 | "peerDependenciesMeta": { 1596 | "supports-color": { 1597 | "optional": true 1598 | } 1599 | } 1600 | }, 1601 | "node_modules/deep-eql": { 1602 | "version": "5.0.2", 1603 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", 1604 | "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", 1605 | "dev": true, 1606 | "license": "MIT", 1607 | "engines": { 1608 | "node": ">=6" 1609 | } 1610 | }, 1611 | "node_modules/deep-is": { 1612 | "version": "0.1.4", 1613 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 1614 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 1615 | "dev": true, 1616 | "license": "MIT" 1617 | }, 1618 | "node_modules/dts-bundle-generator": { 1619 | "version": "9.5.1", 1620 | "resolved": "https://registry.npmjs.org/dts-bundle-generator/-/dts-bundle-generator-9.5.1.tgz", 1621 | "integrity": "sha512-DxpJOb2FNnEyOzMkG11sxO2dmxPjthoVWxfKqWYJ/bI/rT1rvTMktF5EKjAYrRZu6Z6t3NhOUZ0sZ5ZXevOfbA==", 1622 | "dev": true, 1623 | "license": "MIT", 1624 | "dependencies": { 1625 | "typescript": ">=5.0.2", 1626 | "yargs": "^17.6.0" 1627 | }, 1628 | "bin": { 1629 | "dts-bundle-generator": "dist/bin/dts-bundle-generator.js" 1630 | }, 1631 | "engines": { 1632 | "node": ">=14.0.0" 1633 | } 1634 | }, 1635 | "node_modules/emoji-regex": { 1636 | "version": "8.0.0", 1637 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1638 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1639 | "dev": true, 1640 | "license": "MIT" 1641 | }, 1642 | "node_modules/es-module-lexer": { 1643 | "version": "1.6.0", 1644 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", 1645 | "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", 1646 | "dev": true, 1647 | "license": "MIT" 1648 | }, 1649 | "node_modules/esbuild": { 1650 | "version": "0.25.0", 1651 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", 1652 | "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", 1653 | "dev": true, 1654 | "hasInstallScript": true, 1655 | "license": "MIT", 1656 | "bin": { 1657 | "esbuild": "bin/esbuild" 1658 | }, 1659 | "engines": { 1660 | "node": ">=18" 1661 | }, 1662 | "optionalDependencies": { 1663 | "@esbuild/aix-ppc64": "0.25.0", 1664 | "@esbuild/android-arm": "0.25.0", 1665 | "@esbuild/android-arm64": "0.25.0", 1666 | "@esbuild/android-x64": "0.25.0", 1667 | "@esbuild/darwin-arm64": "0.25.0", 1668 | "@esbuild/darwin-x64": "0.25.0", 1669 | "@esbuild/freebsd-arm64": "0.25.0", 1670 | "@esbuild/freebsd-x64": "0.25.0", 1671 | "@esbuild/linux-arm": "0.25.0", 1672 | "@esbuild/linux-arm64": "0.25.0", 1673 | "@esbuild/linux-ia32": "0.25.0", 1674 | "@esbuild/linux-loong64": "0.25.0", 1675 | "@esbuild/linux-mips64el": "0.25.0", 1676 | "@esbuild/linux-ppc64": "0.25.0", 1677 | "@esbuild/linux-riscv64": "0.25.0", 1678 | "@esbuild/linux-s390x": "0.25.0", 1679 | "@esbuild/linux-x64": "0.25.0", 1680 | "@esbuild/netbsd-arm64": "0.25.0", 1681 | "@esbuild/netbsd-x64": "0.25.0", 1682 | "@esbuild/openbsd-arm64": "0.25.0", 1683 | "@esbuild/openbsd-x64": "0.25.0", 1684 | "@esbuild/sunos-x64": "0.25.0", 1685 | "@esbuild/win32-arm64": "0.25.0", 1686 | "@esbuild/win32-ia32": "0.25.0", 1687 | "@esbuild/win32-x64": "0.25.0" 1688 | } 1689 | }, 1690 | "node_modules/escalade": { 1691 | "version": "3.2.0", 1692 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 1693 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1694 | "dev": true, 1695 | "license": "MIT", 1696 | "engines": { 1697 | "node": ">=6" 1698 | } 1699 | }, 1700 | "node_modules/escape-string-regexp": { 1701 | "version": "4.0.0", 1702 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1703 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1704 | "dev": true, 1705 | "license": "MIT", 1706 | "engines": { 1707 | "node": ">=10" 1708 | }, 1709 | "funding": { 1710 | "url": "https://github.com/sponsors/sindresorhus" 1711 | } 1712 | }, 1713 | "node_modules/eslint": { 1714 | "version": "9.21.0", 1715 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", 1716 | "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", 1717 | "dev": true, 1718 | "license": "MIT", 1719 | "dependencies": { 1720 | "@eslint-community/eslint-utils": "^4.2.0", 1721 | "@eslint-community/regexpp": "^4.12.1", 1722 | "@eslint/config-array": "^0.19.2", 1723 | "@eslint/core": "^0.12.0", 1724 | "@eslint/eslintrc": "^3.3.0", 1725 | "@eslint/js": "9.21.0", 1726 | "@eslint/plugin-kit": "^0.2.7", 1727 | "@humanfs/node": "^0.16.6", 1728 | "@humanwhocodes/module-importer": "^1.0.1", 1729 | "@humanwhocodes/retry": "^0.4.2", 1730 | "@types/estree": "^1.0.6", 1731 | "@types/json-schema": "^7.0.15", 1732 | "ajv": "^6.12.4", 1733 | "chalk": "^4.0.0", 1734 | "cross-spawn": "^7.0.6", 1735 | "debug": "^4.3.2", 1736 | "escape-string-regexp": "^4.0.0", 1737 | "eslint-scope": "^8.2.0", 1738 | "eslint-visitor-keys": "^4.2.0", 1739 | "espree": "^10.3.0", 1740 | "esquery": "^1.5.0", 1741 | "esutils": "^2.0.2", 1742 | "fast-deep-equal": "^3.1.3", 1743 | "file-entry-cache": "^8.0.0", 1744 | "find-up": "^5.0.0", 1745 | "glob-parent": "^6.0.2", 1746 | "ignore": "^5.2.0", 1747 | "imurmurhash": "^0.1.4", 1748 | "is-glob": "^4.0.0", 1749 | "json-stable-stringify-without-jsonify": "^1.0.1", 1750 | "lodash.merge": "^4.6.2", 1751 | "minimatch": "^3.1.2", 1752 | "natural-compare": "^1.4.0", 1753 | "optionator": "^0.9.3" 1754 | }, 1755 | "bin": { 1756 | "eslint": "bin/eslint.js" 1757 | }, 1758 | "engines": { 1759 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1760 | }, 1761 | "funding": { 1762 | "url": "https://eslint.org/donate" 1763 | }, 1764 | "peerDependencies": { 1765 | "jiti": "*" 1766 | }, 1767 | "peerDependenciesMeta": { 1768 | "jiti": { 1769 | "optional": true 1770 | } 1771 | } 1772 | }, 1773 | "node_modules/eslint-scope": { 1774 | "version": "8.2.0", 1775 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", 1776 | "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", 1777 | "dev": true, 1778 | "license": "BSD-2-Clause", 1779 | "dependencies": { 1780 | "esrecurse": "^4.3.0", 1781 | "estraverse": "^5.2.0" 1782 | }, 1783 | "engines": { 1784 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1785 | }, 1786 | "funding": { 1787 | "url": "https://opencollective.com/eslint" 1788 | } 1789 | }, 1790 | "node_modules/eslint-visitor-keys": { 1791 | "version": "4.2.0", 1792 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 1793 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 1794 | "dev": true, 1795 | "license": "Apache-2.0", 1796 | "engines": { 1797 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1798 | }, 1799 | "funding": { 1800 | "url": "https://opencollective.com/eslint" 1801 | } 1802 | }, 1803 | "node_modules/espree": { 1804 | "version": "10.3.0", 1805 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", 1806 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", 1807 | "dev": true, 1808 | "license": "BSD-2-Clause", 1809 | "dependencies": { 1810 | "acorn": "^8.14.0", 1811 | "acorn-jsx": "^5.3.2", 1812 | "eslint-visitor-keys": "^4.2.0" 1813 | }, 1814 | "engines": { 1815 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1816 | }, 1817 | "funding": { 1818 | "url": "https://opencollective.com/eslint" 1819 | } 1820 | }, 1821 | "node_modules/esquery": { 1822 | "version": "1.6.0", 1823 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 1824 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 1825 | "dev": true, 1826 | "license": "BSD-3-Clause", 1827 | "dependencies": { 1828 | "estraverse": "^5.1.0" 1829 | }, 1830 | "engines": { 1831 | "node": ">=0.10" 1832 | } 1833 | }, 1834 | "node_modules/esrecurse": { 1835 | "version": "4.3.0", 1836 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1837 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1838 | "dev": true, 1839 | "license": "BSD-2-Clause", 1840 | "dependencies": { 1841 | "estraverse": "^5.2.0" 1842 | }, 1843 | "engines": { 1844 | "node": ">=4.0" 1845 | } 1846 | }, 1847 | "node_modules/estraverse": { 1848 | "version": "5.3.0", 1849 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1850 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1851 | "dev": true, 1852 | "license": "BSD-2-Clause", 1853 | "engines": { 1854 | "node": ">=4.0" 1855 | } 1856 | }, 1857 | "node_modules/esutils": { 1858 | "version": "2.0.3", 1859 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1860 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1861 | "dev": true, 1862 | "license": "BSD-2-Clause", 1863 | "engines": { 1864 | "node": ">=0.10.0" 1865 | } 1866 | }, 1867 | "node_modules/expect-type": { 1868 | "version": "1.1.0", 1869 | "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", 1870 | "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", 1871 | "dev": true, 1872 | "license": "Apache-2.0", 1873 | "engines": { 1874 | "node": ">=12.0.0" 1875 | } 1876 | }, 1877 | "node_modules/fast-deep-equal": { 1878 | "version": "3.1.3", 1879 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1880 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1881 | "dev": true, 1882 | "license": "MIT" 1883 | }, 1884 | "node_modules/fast-glob": { 1885 | "version": "3.3.3", 1886 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", 1887 | "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", 1888 | "dev": true, 1889 | "license": "MIT", 1890 | "dependencies": { 1891 | "@nodelib/fs.stat": "^2.0.2", 1892 | "@nodelib/fs.walk": "^1.2.3", 1893 | "glob-parent": "^5.1.2", 1894 | "merge2": "^1.3.0", 1895 | "micromatch": "^4.0.8" 1896 | }, 1897 | "engines": { 1898 | "node": ">=8.6.0" 1899 | } 1900 | }, 1901 | "node_modules/fast-glob/node_modules/glob-parent": { 1902 | "version": "5.1.2", 1903 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1904 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1905 | "dev": true, 1906 | "license": "ISC", 1907 | "dependencies": { 1908 | "is-glob": "^4.0.1" 1909 | }, 1910 | "engines": { 1911 | "node": ">= 6" 1912 | } 1913 | }, 1914 | "node_modules/fast-json-stable-stringify": { 1915 | "version": "2.1.0", 1916 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1917 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1918 | "dev": true, 1919 | "license": "MIT" 1920 | }, 1921 | "node_modules/fast-levenshtein": { 1922 | "version": "2.0.6", 1923 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1924 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1925 | "dev": true, 1926 | "license": "MIT" 1927 | }, 1928 | "node_modules/fastq": { 1929 | "version": "1.19.1", 1930 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", 1931 | "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", 1932 | "dev": true, 1933 | "license": "ISC", 1934 | "dependencies": { 1935 | "reusify": "^1.0.4" 1936 | } 1937 | }, 1938 | "node_modules/file-entry-cache": { 1939 | "version": "8.0.0", 1940 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 1941 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 1942 | "dev": true, 1943 | "license": "MIT", 1944 | "dependencies": { 1945 | "flat-cache": "^4.0.0" 1946 | }, 1947 | "engines": { 1948 | "node": ">=16.0.0" 1949 | } 1950 | }, 1951 | "node_modules/fill-range": { 1952 | "version": "7.1.1", 1953 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 1954 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 1955 | "dev": true, 1956 | "license": "MIT", 1957 | "dependencies": { 1958 | "to-regex-range": "^5.0.1" 1959 | }, 1960 | "engines": { 1961 | "node": ">=8" 1962 | } 1963 | }, 1964 | "node_modules/find-up": { 1965 | "version": "5.0.0", 1966 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1967 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1968 | "dev": true, 1969 | "license": "MIT", 1970 | "dependencies": { 1971 | "locate-path": "^6.0.0", 1972 | "path-exists": "^4.0.0" 1973 | }, 1974 | "engines": { 1975 | "node": ">=10" 1976 | }, 1977 | "funding": { 1978 | "url": "https://github.com/sponsors/sindresorhus" 1979 | } 1980 | }, 1981 | "node_modules/flat-cache": { 1982 | "version": "4.0.1", 1983 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 1984 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 1985 | "dev": true, 1986 | "license": "MIT", 1987 | "dependencies": { 1988 | "flatted": "^3.2.9", 1989 | "keyv": "^4.5.4" 1990 | }, 1991 | "engines": { 1992 | "node": ">=16" 1993 | } 1994 | }, 1995 | "node_modules/flatted": { 1996 | "version": "3.3.3", 1997 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 1998 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 1999 | "dev": true, 2000 | "license": "ISC" 2001 | }, 2002 | "node_modules/fsevents": { 2003 | "version": "2.3.3", 2004 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 2005 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 2006 | "dev": true, 2007 | "hasInstallScript": true, 2008 | "license": "MIT", 2009 | "optional": true, 2010 | "os": [ 2011 | "darwin" 2012 | ], 2013 | "engines": { 2014 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 2015 | } 2016 | }, 2017 | "node_modules/functional-red-black-tree": { 2018 | "version": "1.0.1", 2019 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 2020 | "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", 2021 | "dev": true, 2022 | "license": "MIT" 2023 | }, 2024 | "node_modules/get-caller-file": { 2025 | "version": "2.0.5", 2026 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 2027 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 2028 | "dev": true, 2029 | "license": "ISC", 2030 | "engines": { 2031 | "node": "6.* || 8.* || >= 10.*" 2032 | } 2033 | }, 2034 | "node_modules/glob-parent": { 2035 | "version": "6.0.2", 2036 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 2037 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2038 | "dev": true, 2039 | "license": "ISC", 2040 | "dependencies": { 2041 | "is-glob": "^4.0.3" 2042 | }, 2043 | "engines": { 2044 | "node": ">=10.13.0" 2045 | } 2046 | }, 2047 | "node_modules/globals": { 2048 | "version": "16.0.0", 2049 | "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", 2050 | "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", 2051 | "dev": true, 2052 | "license": "MIT", 2053 | "engines": { 2054 | "node": ">=18" 2055 | }, 2056 | "funding": { 2057 | "url": "https://github.com/sponsors/sindresorhus" 2058 | } 2059 | }, 2060 | "node_modules/google-closure-library": { 2061 | "version": "20210406.0.0", 2062 | "resolved": "https://registry.npmjs.org/google-closure-library/-/google-closure-library-20210406.0.0.tgz", 2063 | "integrity": "sha512-1lAC/KC9R2QM6nygniM0pRcGrv5bkCUrIZb2hXFxLtAkA+zRiVeWtRYpFWDHXXJzkavKjsn9upiffL4x/nmmVg==", 2064 | "dev": true, 2065 | "license": "Apache-2.0" 2066 | }, 2067 | "node_modules/graphemer": { 2068 | "version": "1.4.0", 2069 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 2070 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 2071 | "dev": true, 2072 | "license": "MIT" 2073 | }, 2074 | "node_modules/has-flag": { 2075 | "version": "4.0.0", 2076 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2077 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2078 | "dev": true, 2079 | "license": "MIT", 2080 | "engines": { 2081 | "node": ">=8" 2082 | } 2083 | }, 2084 | "node_modules/ignore": { 2085 | "version": "5.3.2", 2086 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 2087 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 2088 | "dev": true, 2089 | "license": "MIT", 2090 | "engines": { 2091 | "node": ">= 4" 2092 | } 2093 | }, 2094 | "node_modules/import-fresh": { 2095 | "version": "3.3.1", 2096 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 2097 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 2098 | "dev": true, 2099 | "license": "MIT", 2100 | "dependencies": { 2101 | "parent-module": "^1.0.0", 2102 | "resolve-from": "^4.0.0" 2103 | }, 2104 | "engines": { 2105 | "node": ">=6" 2106 | }, 2107 | "funding": { 2108 | "url": "https://github.com/sponsors/sindresorhus" 2109 | } 2110 | }, 2111 | "node_modules/imurmurhash": { 2112 | "version": "0.1.4", 2113 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 2114 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 2115 | "dev": true, 2116 | "license": "MIT", 2117 | "engines": { 2118 | "node": ">=0.8.19" 2119 | } 2120 | }, 2121 | "node_modules/is-extglob": { 2122 | "version": "2.1.1", 2123 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 2124 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 2125 | "dev": true, 2126 | "license": "MIT", 2127 | "engines": { 2128 | "node": ">=0.10.0" 2129 | } 2130 | }, 2131 | "node_modules/is-fullwidth-code-point": { 2132 | "version": "3.0.0", 2133 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2134 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2135 | "dev": true, 2136 | "license": "MIT", 2137 | "engines": { 2138 | "node": ">=8" 2139 | } 2140 | }, 2141 | "node_modules/is-glob": { 2142 | "version": "4.0.3", 2143 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 2144 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2145 | "dev": true, 2146 | "license": "MIT", 2147 | "dependencies": { 2148 | "is-extglob": "^2.1.1" 2149 | }, 2150 | "engines": { 2151 | "node": ">=0.10.0" 2152 | } 2153 | }, 2154 | "node_modules/is-number": { 2155 | "version": "7.0.0", 2156 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 2157 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 2158 | "dev": true, 2159 | "license": "MIT", 2160 | "engines": { 2161 | "node": ">=0.12.0" 2162 | } 2163 | }, 2164 | "node_modules/isexe": { 2165 | "version": "2.0.0", 2166 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 2167 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 2168 | "dev": true, 2169 | "license": "ISC" 2170 | }, 2171 | "node_modules/js-yaml": { 2172 | "version": "4.1.0", 2173 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2174 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2175 | "dev": true, 2176 | "license": "MIT", 2177 | "dependencies": { 2178 | "argparse": "^2.0.1" 2179 | }, 2180 | "bin": { 2181 | "js-yaml": "bin/js-yaml.js" 2182 | } 2183 | }, 2184 | "node_modules/json-buffer": { 2185 | "version": "3.0.1", 2186 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 2187 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 2188 | "dev": true, 2189 | "license": "MIT" 2190 | }, 2191 | "node_modules/json-schema-traverse": { 2192 | "version": "0.4.1", 2193 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 2194 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 2195 | "dev": true, 2196 | "license": "MIT" 2197 | }, 2198 | "node_modules/json-stable-stringify-without-jsonify": { 2199 | "version": "1.0.1", 2200 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 2201 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 2202 | "dev": true, 2203 | "license": "MIT" 2204 | }, 2205 | "node_modules/keyv": { 2206 | "version": "4.5.4", 2207 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 2208 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 2209 | "dev": true, 2210 | "license": "MIT", 2211 | "dependencies": { 2212 | "json-buffer": "3.0.1" 2213 | } 2214 | }, 2215 | "node_modules/levn": { 2216 | "version": "0.4.1", 2217 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 2218 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 2219 | "dev": true, 2220 | "license": "MIT", 2221 | "dependencies": { 2222 | "prelude-ls": "^1.2.1", 2223 | "type-check": "~0.4.0" 2224 | }, 2225 | "engines": { 2226 | "node": ">= 0.8.0" 2227 | } 2228 | }, 2229 | "node_modules/locate-path": { 2230 | "version": "6.0.0", 2231 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 2232 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 2233 | "dev": true, 2234 | "license": "MIT", 2235 | "dependencies": { 2236 | "p-locate": "^5.0.0" 2237 | }, 2238 | "engines": { 2239 | "node": ">=10" 2240 | }, 2241 | "funding": { 2242 | "url": "https://github.com/sponsors/sindresorhus" 2243 | } 2244 | }, 2245 | "node_modules/lodash": { 2246 | "version": "4.17.21", 2247 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 2248 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 2249 | "dev": true, 2250 | "license": "MIT" 2251 | }, 2252 | "node_modules/lodash.merge": { 2253 | "version": "4.6.2", 2254 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 2255 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 2256 | "dev": true, 2257 | "license": "MIT" 2258 | }, 2259 | "node_modules/loupe": { 2260 | "version": "3.1.3", 2261 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", 2262 | "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", 2263 | "dev": true, 2264 | "license": "MIT" 2265 | }, 2266 | "node_modules/magic-string": { 2267 | "version": "0.30.17", 2268 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", 2269 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 2270 | "dev": true, 2271 | "license": "MIT", 2272 | "dependencies": { 2273 | "@jridgewell/sourcemap-codec": "^1.5.0" 2274 | } 2275 | }, 2276 | "node_modules/merge2": { 2277 | "version": "1.4.1", 2278 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 2279 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 2280 | "dev": true, 2281 | "license": "MIT", 2282 | "engines": { 2283 | "node": ">= 8" 2284 | } 2285 | }, 2286 | "node_modules/micromatch": { 2287 | "version": "4.0.8", 2288 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 2289 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 2290 | "dev": true, 2291 | "license": "MIT", 2292 | "dependencies": { 2293 | "braces": "^3.0.3", 2294 | "picomatch": "^2.3.1" 2295 | }, 2296 | "engines": { 2297 | "node": ">=8.6" 2298 | } 2299 | }, 2300 | "node_modules/minimatch": { 2301 | "version": "3.1.2", 2302 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2303 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2304 | "dev": true, 2305 | "license": "ISC", 2306 | "dependencies": { 2307 | "brace-expansion": "^1.1.7" 2308 | }, 2309 | "engines": { 2310 | "node": "*" 2311 | } 2312 | }, 2313 | "node_modules/ms": { 2314 | "version": "2.1.3", 2315 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2316 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 2317 | "dev": true, 2318 | "license": "MIT" 2319 | }, 2320 | "node_modules/nanoid": { 2321 | "version": "3.3.8", 2322 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 2323 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 2324 | "dev": true, 2325 | "funding": [ 2326 | { 2327 | "type": "github", 2328 | "url": "https://github.com/sponsors/ai" 2329 | } 2330 | ], 2331 | "license": "MIT", 2332 | "bin": { 2333 | "nanoid": "bin/nanoid.cjs" 2334 | }, 2335 | "engines": { 2336 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 2337 | } 2338 | }, 2339 | "node_modules/natural-compare": { 2340 | "version": "1.4.0", 2341 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2342 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 2343 | "dev": true, 2344 | "license": "MIT" 2345 | }, 2346 | "node_modules/optionator": { 2347 | "version": "0.9.4", 2348 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 2349 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 2350 | "dev": true, 2351 | "license": "MIT", 2352 | "dependencies": { 2353 | "deep-is": "^0.1.3", 2354 | "fast-levenshtein": "^2.0.6", 2355 | "levn": "^0.4.1", 2356 | "prelude-ls": "^1.2.1", 2357 | "type-check": "^0.4.0", 2358 | "word-wrap": "^1.2.5" 2359 | }, 2360 | "engines": { 2361 | "node": ">= 0.8.0" 2362 | } 2363 | }, 2364 | "node_modules/p-limit": { 2365 | "version": "3.1.0", 2366 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 2367 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 2368 | "dev": true, 2369 | "license": "MIT", 2370 | "dependencies": { 2371 | "yocto-queue": "^0.1.0" 2372 | }, 2373 | "engines": { 2374 | "node": ">=10" 2375 | }, 2376 | "funding": { 2377 | "url": "https://github.com/sponsors/sindresorhus" 2378 | } 2379 | }, 2380 | "node_modules/p-locate": { 2381 | "version": "5.0.0", 2382 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 2383 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 2384 | "dev": true, 2385 | "license": "MIT", 2386 | "dependencies": { 2387 | "p-limit": "^3.0.2" 2388 | }, 2389 | "engines": { 2390 | "node": ">=10" 2391 | }, 2392 | "funding": { 2393 | "url": "https://github.com/sponsors/sindresorhus" 2394 | } 2395 | }, 2396 | "node_modules/parent-module": { 2397 | "version": "1.0.1", 2398 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2399 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2400 | "dev": true, 2401 | "license": "MIT", 2402 | "dependencies": { 2403 | "callsites": "^3.0.0" 2404 | }, 2405 | "engines": { 2406 | "node": ">=6" 2407 | } 2408 | }, 2409 | "node_modules/path-exists": { 2410 | "version": "4.0.0", 2411 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 2412 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 2413 | "dev": true, 2414 | "license": "MIT", 2415 | "engines": { 2416 | "node": ">=8" 2417 | } 2418 | }, 2419 | "node_modules/path-key": { 2420 | "version": "3.1.1", 2421 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2422 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2423 | "dev": true, 2424 | "license": "MIT", 2425 | "engines": { 2426 | "node": ">=8" 2427 | } 2428 | }, 2429 | "node_modules/pathe": { 2430 | "version": "2.0.3", 2431 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", 2432 | "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", 2433 | "dev": true, 2434 | "license": "MIT" 2435 | }, 2436 | "node_modules/pathval": { 2437 | "version": "2.0.0", 2438 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", 2439 | "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", 2440 | "dev": true, 2441 | "license": "MIT", 2442 | "engines": { 2443 | "node": ">= 14.16" 2444 | } 2445 | }, 2446 | "node_modules/picocolors": { 2447 | "version": "1.1.1", 2448 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 2449 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 2450 | "dev": true, 2451 | "license": "ISC" 2452 | }, 2453 | "node_modules/picomatch": { 2454 | "version": "2.3.1", 2455 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2456 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2457 | "dev": true, 2458 | "license": "MIT", 2459 | "engines": { 2460 | "node": ">=8.6" 2461 | }, 2462 | "funding": { 2463 | "url": "https://github.com/sponsors/jonschlinkert" 2464 | } 2465 | }, 2466 | "node_modules/platform": { 2467 | "version": "1.3.6", 2468 | "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", 2469 | "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", 2470 | "dev": true, 2471 | "license": "MIT" 2472 | }, 2473 | "node_modules/postcss": { 2474 | "version": "8.5.3", 2475 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", 2476 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 2477 | "dev": true, 2478 | "funding": [ 2479 | { 2480 | "type": "opencollective", 2481 | "url": "https://opencollective.com/postcss/" 2482 | }, 2483 | { 2484 | "type": "tidelift", 2485 | "url": "https://tidelift.com/funding/github/npm/postcss" 2486 | }, 2487 | { 2488 | "type": "github", 2489 | "url": "https://github.com/sponsors/ai" 2490 | } 2491 | ], 2492 | "license": "MIT", 2493 | "dependencies": { 2494 | "nanoid": "^3.3.8", 2495 | "picocolors": "^1.1.1", 2496 | "source-map-js": "^1.2.1" 2497 | }, 2498 | "engines": { 2499 | "node": "^10 || ^12 || >=14" 2500 | } 2501 | }, 2502 | "node_modules/prelude-ls": { 2503 | "version": "1.2.1", 2504 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 2505 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 2506 | "dev": true, 2507 | "license": "MIT", 2508 | "engines": { 2509 | "node": ">= 0.8.0" 2510 | } 2511 | }, 2512 | "node_modules/punycode": { 2513 | "version": "2.3.1", 2514 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 2515 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 2516 | "dev": true, 2517 | "license": "MIT", 2518 | "engines": { 2519 | "node": ">=6" 2520 | } 2521 | }, 2522 | "node_modules/queue-microtask": { 2523 | "version": "1.2.3", 2524 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 2525 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 2526 | "dev": true, 2527 | "funding": [ 2528 | { 2529 | "type": "github", 2530 | "url": "https://github.com/sponsors/feross" 2531 | }, 2532 | { 2533 | "type": "patreon", 2534 | "url": "https://www.patreon.com/feross" 2535 | }, 2536 | { 2537 | "type": "consulting", 2538 | "url": "https://feross.org/support" 2539 | } 2540 | ], 2541 | "license": "MIT" 2542 | }, 2543 | "node_modules/require-directory": { 2544 | "version": "2.1.1", 2545 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2546 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 2547 | "dev": true, 2548 | "license": "MIT", 2549 | "engines": { 2550 | "node": ">=0.10.0" 2551 | } 2552 | }, 2553 | "node_modules/resolve-from": { 2554 | "version": "4.0.0", 2555 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2556 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2557 | "dev": true, 2558 | "license": "MIT", 2559 | "engines": { 2560 | "node": ">=4" 2561 | } 2562 | }, 2563 | "node_modules/reusify": { 2564 | "version": "1.1.0", 2565 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", 2566 | "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", 2567 | "dev": true, 2568 | "license": "MIT", 2569 | "engines": { 2570 | "iojs": ">=1.0.0", 2571 | "node": ">=0.10.0" 2572 | } 2573 | }, 2574 | "node_modules/rollup": { 2575 | "version": "4.34.8", 2576 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", 2577 | "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", 2578 | "dev": true, 2579 | "license": "MIT", 2580 | "dependencies": { 2581 | "@types/estree": "1.0.6" 2582 | }, 2583 | "bin": { 2584 | "rollup": "dist/bin/rollup" 2585 | }, 2586 | "engines": { 2587 | "node": ">=18.0.0", 2588 | "npm": ">=8.0.0" 2589 | }, 2590 | "optionalDependencies": { 2591 | "@rollup/rollup-android-arm-eabi": "4.34.8", 2592 | "@rollup/rollup-android-arm64": "4.34.8", 2593 | "@rollup/rollup-darwin-arm64": "4.34.8", 2594 | "@rollup/rollup-darwin-x64": "4.34.8", 2595 | "@rollup/rollup-freebsd-arm64": "4.34.8", 2596 | "@rollup/rollup-freebsd-x64": "4.34.8", 2597 | "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", 2598 | "@rollup/rollup-linux-arm-musleabihf": "4.34.8", 2599 | "@rollup/rollup-linux-arm64-gnu": "4.34.8", 2600 | "@rollup/rollup-linux-arm64-musl": "4.34.8", 2601 | "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", 2602 | "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", 2603 | "@rollup/rollup-linux-riscv64-gnu": "4.34.8", 2604 | "@rollup/rollup-linux-s390x-gnu": "4.34.8", 2605 | "@rollup/rollup-linux-x64-gnu": "4.34.8", 2606 | "@rollup/rollup-linux-x64-musl": "4.34.8", 2607 | "@rollup/rollup-win32-arm64-msvc": "4.34.8", 2608 | "@rollup/rollup-win32-ia32-msvc": "4.34.8", 2609 | "@rollup/rollup-win32-x64-msvc": "4.34.8", 2610 | "fsevents": "~2.3.2" 2611 | } 2612 | }, 2613 | "node_modules/run-parallel": { 2614 | "version": "1.2.0", 2615 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 2616 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 2617 | "dev": true, 2618 | "funding": [ 2619 | { 2620 | "type": "github", 2621 | "url": "https://github.com/sponsors/feross" 2622 | }, 2623 | { 2624 | "type": "patreon", 2625 | "url": "https://www.patreon.com/feross" 2626 | }, 2627 | { 2628 | "type": "consulting", 2629 | "url": "https://feross.org/support" 2630 | } 2631 | ], 2632 | "license": "MIT", 2633 | "dependencies": { 2634 | "queue-microtask": "^1.2.2" 2635 | } 2636 | }, 2637 | "node_modules/semver": { 2638 | "version": "7.7.1", 2639 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", 2640 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", 2641 | "dev": true, 2642 | "license": "ISC", 2643 | "bin": { 2644 | "semver": "bin/semver.js" 2645 | }, 2646 | "engines": { 2647 | "node": ">=10" 2648 | } 2649 | }, 2650 | "node_modules/shebang-command": { 2651 | "version": "2.0.0", 2652 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2653 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2654 | "dev": true, 2655 | "license": "MIT", 2656 | "dependencies": { 2657 | "shebang-regex": "^3.0.0" 2658 | }, 2659 | "engines": { 2660 | "node": ">=8" 2661 | } 2662 | }, 2663 | "node_modules/shebang-regex": { 2664 | "version": "3.0.0", 2665 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2666 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2667 | "dev": true, 2668 | "license": "MIT", 2669 | "engines": { 2670 | "node": ">=8" 2671 | } 2672 | }, 2673 | "node_modules/siginfo": { 2674 | "version": "2.0.0", 2675 | "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", 2676 | "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", 2677 | "dev": true, 2678 | "license": "ISC" 2679 | }, 2680 | "node_modules/source-map-js": { 2681 | "version": "1.2.1", 2682 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 2683 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 2684 | "dev": true, 2685 | "license": "BSD-3-Clause", 2686 | "engines": { 2687 | "node": ">=0.10.0" 2688 | } 2689 | }, 2690 | "node_modules/stackback": { 2691 | "version": "0.0.2", 2692 | "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", 2693 | "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", 2694 | "dev": true, 2695 | "license": "MIT" 2696 | }, 2697 | "node_modules/std-env": { 2698 | "version": "3.8.0", 2699 | "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", 2700 | "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", 2701 | "dev": true, 2702 | "license": "MIT" 2703 | }, 2704 | "node_modules/string-width": { 2705 | "version": "4.2.3", 2706 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2707 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2708 | "dev": true, 2709 | "license": "MIT", 2710 | "dependencies": { 2711 | "emoji-regex": "^8.0.0", 2712 | "is-fullwidth-code-point": "^3.0.0", 2713 | "strip-ansi": "^6.0.1" 2714 | }, 2715 | "engines": { 2716 | "node": ">=8" 2717 | } 2718 | }, 2719 | "node_modules/strip-ansi": { 2720 | "version": "6.0.1", 2721 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2722 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2723 | "dev": true, 2724 | "license": "MIT", 2725 | "dependencies": { 2726 | "ansi-regex": "^5.0.1" 2727 | }, 2728 | "engines": { 2729 | "node": ">=8" 2730 | } 2731 | }, 2732 | "node_modules/strip-json-comments": { 2733 | "version": "3.1.1", 2734 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2735 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2736 | "dev": true, 2737 | "license": "MIT", 2738 | "engines": { 2739 | "node": ">=8" 2740 | }, 2741 | "funding": { 2742 | "url": "https://github.com/sponsors/sindresorhus" 2743 | } 2744 | }, 2745 | "node_modules/supports-color": { 2746 | "version": "7.2.0", 2747 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2748 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2749 | "dev": true, 2750 | "license": "MIT", 2751 | "dependencies": { 2752 | "has-flag": "^4.0.0" 2753 | }, 2754 | "engines": { 2755 | "node": ">=8" 2756 | } 2757 | }, 2758 | "node_modules/tinybench": { 2759 | "version": "2.9.0", 2760 | "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", 2761 | "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", 2762 | "dev": true, 2763 | "license": "MIT" 2764 | }, 2765 | "node_modules/tinyexec": { 2766 | "version": "0.3.2", 2767 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", 2768 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", 2769 | "dev": true, 2770 | "license": "MIT" 2771 | }, 2772 | "node_modules/tinypool": { 2773 | "version": "1.0.2", 2774 | "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", 2775 | "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", 2776 | "dev": true, 2777 | "license": "MIT", 2778 | "engines": { 2779 | "node": "^18.0.0 || >=20.0.0" 2780 | } 2781 | }, 2782 | "node_modules/tinyrainbow": { 2783 | "version": "2.0.0", 2784 | "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", 2785 | "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", 2786 | "dev": true, 2787 | "license": "MIT", 2788 | "engines": { 2789 | "node": ">=14.0.0" 2790 | } 2791 | }, 2792 | "node_modules/tinyspy": { 2793 | "version": "3.0.2", 2794 | "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", 2795 | "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", 2796 | "dev": true, 2797 | "license": "MIT", 2798 | "engines": { 2799 | "node": ">=14.0.0" 2800 | } 2801 | }, 2802 | "node_modules/to-regex-range": { 2803 | "version": "5.0.1", 2804 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2805 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2806 | "dev": true, 2807 | "license": "MIT", 2808 | "dependencies": { 2809 | "is-number": "^7.0.0" 2810 | }, 2811 | "engines": { 2812 | "node": ">=8.0" 2813 | } 2814 | }, 2815 | "node_modules/ts-api-utils": { 2816 | "version": "2.0.1", 2817 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", 2818 | "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", 2819 | "dev": true, 2820 | "license": "MIT", 2821 | "engines": { 2822 | "node": ">=18.12" 2823 | }, 2824 | "peerDependencies": { 2825 | "typescript": ">=4.8.4" 2826 | } 2827 | }, 2828 | "node_modules/type-check": { 2829 | "version": "0.4.0", 2830 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2831 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2832 | "dev": true, 2833 | "license": "MIT", 2834 | "dependencies": { 2835 | "prelude-ls": "^1.2.1" 2836 | }, 2837 | "engines": { 2838 | "node": ">= 0.8.0" 2839 | } 2840 | }, 2841 | "node_modules/typescript": { 2842 | "version": "5.7.3", 2843 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", 2844 | "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", 2845 | "dev": true, 2846 | "license": "Apache-2.0", 2847 | "bin": { 2848 | "tsc": "bin/tsc", 2849 | "tsserver": "bin/tsserver" 2850 | }, 2851 | "engines": { 2852 | "node": ">=14.17" 2853 | } 2854 | }, 2855 | "node_modules/typescript-eslint": { 2856 | "version": "8.25.0", 2857 | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.25.0.tgz", 2858 | "integrity": "sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==", 2859 | "dev": true, 2860 | "license": "MIT", 2861 | "dependencies": { 2862 | "@typescript-eslint/eslint-plugin": "8.25.0", 2863 | "@typescript-eslint/parser": "8.25.0", 2864 | "@typescript-eslint/utils": "8.25.0" 2865 | }, 2866 | "engines": { 2867 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2868 | }, 2869 | "funding": { 2870 | "type": "opencollective", 2871 | "url": "https://opencollective.com/typescript-eslint" 2872 | }, 2873 | "peerDependencies": { 2874 | "eslint": "^8.57.0 || ^9.0.0", 2875 | "typescript": ">=4.8.4 <5.8.0" 2876 | } 2877 | }, 2878 | "node_modules/undici-types": { 2879 | "version": "6.20.0", 2880 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 2881 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 2882 | "dev": true, 2883 | "license": "MIT", 2884 | "optional": true, 2885 | "peer": true 2886 | }, 2887 | "node_modules/uri-js": { 2888 | "version": "4.4.1", 2889 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2890 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2891 | "dev": true, 2892 | "license": "BSD-2-Clause", 2893 | "dependencies": { 2894 | "punycode": "^2.1.0" 2895 | } 2896 | }, 2897 | "node_modules/vite": { 2898 | "version": "6.2.0", 2899 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", 2900 | "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", 2901 | "dev": true, 2902 | "license": "MIT", 2903 | "dependencies": { 2904 | "esbuild": "^0.25.0", 2905 | "postcss": "^8.5.3", 2906 | "rollup": "^4.30.1" 2907 | }, 2908 | "bin": { 2909 | "vite": "bin/vite.js" 2910 | }, 2911 | "engines": { 2912 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 2913 | }, 2914 | "funding": { 2915 | "url": "https://github.com/vitejs/vite?sponsor=1" 2916 | }, 2917 | "optionalDependencies": { 2918 | "fsevents": "~2.3.3" 2919 | }, 2920 | "peerDependencies": { 2921 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 2922 | "jiti": ">=1.21.0", 2923 | "less": "*", 2924 | "lightningcss": "^1.21.0", 2925 | "sass": "*", 2926 | "sass-embedded": "*", 2927 | "stylus": "*", 2928 | "sugarss": "*", 2929 | "terser": "^5.16.0", 2930 | "tsx": "^4.8.1", 2931 | "yaml": "^2.4.2" 2932 | }, 2933 | "peerDependenciesMeta": { 2934 | "@types/node": { 2935 | "optional": true 2936 | }, 2937 | "jiti": { 2938 | "optional": true 2939 | }, 2940 | "less": { 2941 | "optional": true 2942 | }, 2943 | "lightningcss": { 2944 | "optional": true 2945 | }, 2946 | "sass": { 2947 | "optional": true 2948 | }, 2949 | "sass-embedded": { 2950 | "optional": true 2951 | }, 2952 | "stylus": { 2953 | "optional": true 2954 | }, 2955 | "sugarss": { 2956 | "optional": true 2957 | }, 2958 | "terser": { 2959 | "optional": true 2960 | }, 2961 | "tsx": { 2962 | "optional": true 2963 | }, 2964 | "yaml": { 2965 | "optional": true 2966 | } 2967 | } 2968 | }, 2969 | "node_modules/vite-node": { 2970 | "version": "3.0.7", 2971 | "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.7.tgz", 2972 | "integrity": "sha512-2fX0QwX4GkkkpULXdT1Pf4q0tC1i1lFOyseKoonavXUNlQ77KpW2XqBGGNIm/J4Ows4KxgGJzDguYVPKwG/n5A==", 2973 | "dev": true, 2974 | "license": "MIT", 2975 | "dependencies": { 2976 | "cac": "^6.7.14", 2977 | "debug": "^4.4.0", 2978 | "es-module-lexer": "^1.6.0", 2979 | "pathe": "^2.0.3", 2980 | "vite": "^5.0.0 || ^6.0.0" 2981 | }, 2982 | "bin": { 2983 | "vite-node": "vite-node.mjs" 2984 | }, 2985 | "engines": { 2986 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 2987 | }, 2988 | "funding": { 2989 | "url": "https://opencollective.com/vitest" 2990 | } 2991 | }, 2992 | "node_modules/vitest": { 2993 | "version": "3.0.7", 2994 | "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.7.tgz", 2995 | "integrity": "sha512-IP7gPK3LS3Fvn44x30X1dM9vtawm0aesAa2yBIZ9vQf+qB69NXC5776+Qmcr7ohUXIQuLhk7xQR0aSUIDPqavg==", 2996 | "dev": true, 2997 | "license": "MIT", 2998 | "dependencies": { 2999 | "@vitest/expect": "3.0.7", 3000 | "@vitest/mocker": "3.0.7", 3001 | "@vitest/pretty-format": "^3.0.7", 3002 | "@vitest/runner": "3.0.7", 3003 | "@vitest/snapshot": "3.0.7", 3004 | "@vitest/spy": "3.0.7", 3005 | "@vitest/utils": "3.0.7", 3006 | "chai": "^5.2.0", 3007 | "debug": "^4.4.0", 3008 | "expect-type": "^1.1.0", 3009 | "magic-string": "^0.30.17", 3010 | "pathe": "^2.0.3", 3011 | "std-env": "^3.8.0", 3012 | "tinybench": "^2.9.0", 3013 | "tinyexec": "^0.3.2", 3014 | "tinypool": "^1.0.2", 3015 | "tinyrainbow": "^2.0.0", 3016 | "vite": "^5.0.0 || ^6.0.0", 3017 | "vite-node": "3.0.7", 3018 | "why-is-node-running": "^2.3.0" 3019 | }, 3020 | "bin": { 3021 | "vitest": "vitest.mjs" 3022 | }, 3023 | "engines": { 3024 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 3025 | }, 3026 | "funding": { 3027 | "url": "https://opencollective.com/vitest" 3028 | }, 3029 | "peerDependencies": { 3030 | "@edge-runtime/vm": "*", 3031 | "@types/debug": "^4.1.12", 3032 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 3033 | "@vitest/browser": "3.0.7", 3034 | "@vitest/ui": "3.0.7", 3035 | "happy-dom": "*", 3036 | "jsdom": "*" 3037 | }, 3038 | "peerDependenciesMeta": { 3039 | "@edge-runtime/vm": { 3040 | "optional": true 3041 | }, 3042 | "@types/debug": { 3043 | "optional": true 3044 | }, 3045 | "@types/node": { 3046 | "optional": true 3047 | }, 3048 | "@vitest/browser": { 3049 | "optional": true 3050 | }, 3051 | "@vitest/ui": { 3052 | "optional": true 3053 | }, 3054 | "happy-dom": { 3055 | "optional": true 3056 | }, 3057 | "jsdom": { 3058 | "optional": true 3059 | } 3060 | } 3061 | }, 3062 | "node_modules/which": { 3063 | "version": "2.0.2", 3064 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 3065 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 3066 | "dev": true, 3067 | "license": "ISC", 3068 | "dependencies": { 3069 | "isexe": "^2.0.0" 3070 | }, 3071 | "bin": { 3072 | "node-which": "bin/node-which" 3073 | }, 3074 | "engines": { 3075 | "node": ">= 8" 3076 | } 3077 | }, 3078 | "node_modules/why-is-node-running": { 3079 | "version": "2.3.0", 3080 | "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", 3081 | "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", 3082 | "dev": true, 3083 | "license": "MIT", 3084 | "dependencies": { 3085 | "siginfo": "^2.0.0", 3086 | "stackback": "0.0.2" 3087 | }, 3088 | "bin": { 3089 | "why-is-node-running": "cli.js" 3090 | }, 3091 | "engines": { 3092 | "node": ">=8" 3093 | } 3094 | }, 3095 | "node_modules/word-wrap": { 3096 | "version": "1.2.5", 3097 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 3098 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 3099 | "dev": true, 3100 | "license": "MIT", 3101 | "engines": { 3102 | "node": ">=0.10.0" 3103 | } 3104 | }, 3105 | "node_modules/wrap-ansi": { 3106 | "version": "7.0.0", 3107 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 3108 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 3109 | "dev": true, 3110 | "license": "MIT", 3111 | "dependencies": { 3112 | "ansi-styles": "^4.0.0", 3113 | "string-width": "^4.1.0", 3114 | "strip-ansi": "^6.0.0" 3115 | }, 3116 | "engines": { 3117 | "node": ">=10" 3118 | }, 3119 | "funding": { 3120 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 3121 | } 3122 | }, 3123 | "node_modules/y18n": { 3124 | "version": "5.0.8", 3125 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 3126 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 3127 | "dev": true, 3128 | "license": "ISC", 3129 | "engines": { 3130 | "node": ">=10" 3131 | } 3132 | }, 3133 | "node_modules/yargs": { 3134 | "version": "17.7.2", 3135 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 3136 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 3137 | "dev": true, 3138 | "license": "MIT", 3139 | "dependencies": { 3140 | "cliui": "^8.0.1", 3141 | "escalade": "^3.1.1", 3142 | "get-caller-file": "^2.0.5", 3143 | "require-directory": "^2.1.1", 3144 | "string-width": "^4.2.3", 3145 | "y18n": "^5.0.5", 3146 | "yargs-parser": "^21.1.1" 3147 | }, 3148 | "engines": { 3149 | "node": ">=12" 3150 | } 3151 | }, 3152 | "node_modules/yargs-parser": { 3153 | "version": "21.1.1", 3154 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 3155 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 3156 | "dev": true, 3157 | "license": "ISC", 3158 | "engines": { 3159 | "node": ">=12" 3160 | } 3161 | }, 3162 | "node_modules/yocto-queue": { 3163 | "version": "0.1.0", 3164 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 3165 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 3166 | "dev": true, 3167 | "license": "MIT", 3168 | "engines": { 3169 | "node": ">=10" 3170 | }, 3171 | "funding": { 3172 | "url": "https://github.com/sponsors/sindresorhus" 3173 | } 3174 | } 3175 | } 3176 | } 3177 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avl", 3 | "version": "1.6.0", 4 | "author": "Alexander Milevski ", 5 | "license": "MIT", 6 | "description": "Fast AVL tree for Node and browser", 7 | "type": "module", 8 | "main": "./dist/index.cjs", 9 | "module": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts", 11 | "exports": { 12 | ".": { 13 | "import": "./dist/index.mjs", 14 | "require": "./dist/index.cjs", 15 | "types": "./dist/index.d.ts" 16 | } 17 | }, 18 | "files": [ 19 | "dist" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/w8r/avl.git" 24 | }, 25 | "scripts": { 26 | "prebuild": "npm run lint", 27 | "lint": "eslint src tests", 28 | "build": "vite build && npm run types", 29 | "types": "npm run types:generate && npm run types:bundle && rm -rf dist/types", 30 | "types:generate": "tsc --declaration --emitDeclarationOnly --declarationDir dist/types", 31 | "types:bundle": "dts-bundle-generator dist/types/index.ts -o dist/index.d.ts", 32 | "benchmark": "node bench/benchmark.mjs", 33 | "start": "npm run test:watch", 34 | "test:watch": "vitest", 35 | "test": "vitest run" 36 | }, 37 | "devDependencies": { 38 | "@types/bintrees": "^1.0.6", 39 | "benchmark": "^2.1.4", 40 | "bintrees": "^1.0.2", 41 | "dts-bundle-generator": "^9.5.1", 42 | "eslint": "^9.21.0", 43 | "functional-red-black-tree": "^1.0.1", 44 | "globals": "^16.0.0", 45 | "google-closure-library": "^20210406.0.0", 46 | "typescript-eslint": "^8.25.0", 47 | "vite": "^6.2.0", 48 | "vitest": "^3.0.7" 49 | }, 50 | "keywords": [ 51 | "binary-tree", 52 | "bst", 53 | "avl-tree", 54 | "avl", 55 | "balanced-search-tree" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { print, isBalanced, loadRecursive, markBalance, sort } from "./utils"; 2 | import type { 3 | AVLNode, 4 | Comparator, 5 | Visitor, 6 | NodeCallback, 7 | NodePrinter, 8 | } from "./types"; 9 | 10 | // function createNode (parent, left, right, height, key, data) { 11 | // return { parent, left, right, balanceFactor: height, key, data }; 12 | // } 13 | 14 | /** 15 | * Default comparison function 16 | */ 17 | function DEFAULT_COMPARE(a: K, b: K): 1 | 0 | -1 { 18 | return a > b ? 1 : a < b ? -1 : 0; 19 | } 20 | 21 | /** 22 | * Single left rotation 23 | * @param {Node} node 24 | * @return {Node} 25 | */ 26 | function rotateLeft(node: AVLNode) { 27 | const rightNode = node.right!; 28 | node.right = rightNode.left; 29 | 30 | if (rightNode.left) rightNode.left.parent = node; 31 | 32 | rightNode.parent = node.parent; 33 | if (rightNode.parent) { 34 | if (rightNode.parent.left === node) { 35 | rightNode.parent.left = rightNode; 36 | } else { 37 | rightNode.parent.right = rightNode; 38 | } 39 | } 40 | 41 | node.parent = rightNode; 42 | rightNode.left = node; 43 | 44 | node.balanceFactor += 1; 45 | if (rightNode.balanceFactor < 0) { 46 | node.balanceFactor -= rightNode.balanceFactor; 47 | } 48 | 49 | rightNode.balanceFactor += 1; 50 | if (node.balanceFactor > 0) { 51 | rightNode.balanceFactor += node.balanceFactor; 52 | } 53 | return rightNode; 54 | } 55 | 56 | function rotateRight(node: AVLNode) { 57 | const leftNode = node.left!; 58 | node.left = leftNode.right; 59 | if (node.left) node.left.parent = node; 60 | 61 | leftNode.parent = node.parent; 62 | if (leftNode.parent) { 63 | if (leftNode.parent.left === node) { 64 | leftNode.parent.left = leftNode; 65 | } else { 66 | leftNode.parent.right = leftNode; 67 | } 68 | } 69 | 70 | node.parent = leftNode; 71 | leftNode.right = node; 72 | 73 | node.balanceFactor -= 1; 74 | if (leftNode.balanceFactor > 0) { 75 | node.balanceFactor -= leftNode.balanceFactor; 76 | } 77 | 78 | leftNode.balanceFactor -= 1; 79 | if (node.balanceFactor < 0) { 80 | leftNode.balanceFactor += node.balanceFactor; 81 | } 82 | 83 | return leftNode; 84 | } 85 | 86 | // function leftBalance (node) { 87 | // if (node.left.balanceFactor === -1) rotateLeft(node.left); 88 | // return rotateRight(node); 89 | // } 90 | 91 | // function rightBalance (node) { 92 | // if (node.right.balanceFactor === 1) rotateRight(node.right); 93 | // return rotateLeft(node); 94 | // } 95 | 96 | export class AVLTree { 97 | private _comparator: Comparator; 98 | private _root: AVLNode | null; 99 | private _size: number; 100 | private _noDuplicates: boolean; 101 | 102 | constructor( 103 | comparator: Comparator = DEFAULT_COMPARE, 104 | noDuplicates = false 105 | ) { 106 | this._comparator = comparator || DEFAULT_COMPARE; 107 | this._root = null; 108 | this._size = 0; 109 | this._noDuplicates = !!noDuplicates; 110 | } 111 | 112 | /** 113 | * Clear the tree 114 | */ 115 | destroy() { 116 | return this.clear(); 117 | } 118 | 119 | /** 120 | * Clear the tree 121 | * @return {AVLTree} 122 | */ 123 | clear() { 124 | this._root = null; 125 | this._size = 0; 126 | return this; 127 | } 128 | 129 | /** 130 | * Number of nodes 131 | * @return {number} 132 | */ 133 | get size() { 134 | return this._size; 135 | } 136 | 137 | get root() { 138 | return this._root; 139 | } 140 | 141 | /** 142 | * Whether the tree contains a node with the given key 143 | */ 144 | contains(key: K) { 145 | if (this._root) { 146 | let node: AVLNode | null = this._root; 147 | const comparator = this._comparator; 148 | while (node) { 149 | const cmp = comparator(key, node.key); 150 | if (cmp === 0) return true; 151 | else if (cmp < 0) node = node.left; 152 | else node = node.right; 153 | } 154 | } 155 | return false; 156 | } 157 | 158 | /** 159 | * Successor node 160 | */ 161 | next(node: AVLNode) { 162 | let successor: AVLNode | null = node; 163 | if (successor) { 164 | if (successor.right) { 165 | successor = successor.right; 166 | while (successor.left) successor = successor.left; 167 | } else { 168 | successor = node.parent; 169 | while (successor && successor.right === node) { 170 | node = successor; 171 | successor = successor.parent; 172 | } 173 | } 174 | } 175 | return successor; 176 | } 177 | 178 | /** 179 | * Predecessor node 180 | */ 181 | prev(node: AVLNode) { 182 | let predecessor: AVLNode | null = node; 183 | if (predecessor) { 184 | if (predecessor.left) { 185 | predecessor = predecessor.left; 186 | while (predecessor.right) predecessor = predecessor.right; 187 | } else { 188 | predecessor = node.parent; 189 | while (predecessor && predecessor.left === node) { 190 | node = predecessor; 191 | predecessor = predecessor.parent; 192 | } 193 | } 194 | } 195 | return predecessor; 196 | } 197 | 198 | /** 199 | * @param {forEachCallback} callback 200 | * @return {AVLTree} 201 | */ 202 | forEach(callback: Visitor) { 203 | let current: AVLNode | null | undefined = this._root; 204 | const s: AVLNode[] = []; 205 | let done = false; 206 | let i = 0; 207 | 208 | while (!done) { 209 | // Reach the left most Node of the current Node 210 | if (current) { 211 | // Place pointer to a tree node on the stack 212 | // before traversing the node's left subtree 213 | s.push(current); 214 | current = current.left; 215 | } else { 216 | // BackTrack from the empty subtree and visit the Node 217 | // at the top of the stack; however, if the stack is 218 | // empty you are done 219 | if (s.length > 0) { 220 | current = s.pop()!; 221 | callback(current, i++); 222 | 223 | // We have visited the node and its left 224 | // subtree. Now, it's right subtree's turn 225 | current = current.right; 226 | } else done = true; 227 | } 228 | } 229 | return this; 230 | } 231 | 232 | /** 233 | * Walk key range from `low` to `high`. Stops if `fn` returns a value. 234 | * @param {Key} low 235 | * @param {Key} high 236 | * @param {Function} fn 237 | * @param {*?} ctx 238 | * @return {SplayTree} 239 | */ 240 | range(low: K, high: K, fn: NodeCallback, ctx?: T) { 241 | const Q: AVLNode[] = []; 242 | const compare = this._comparator; 243 | let node = this._root; 244 | 245 | while (Q.length !== 0 || node) { 246 | if (node) { 247 | Q.push(node); 248 | node = node.left; 249 | } else { 250 | node = Q.pop()!; 251 | const cmp = compare(node.key, high); 252 | if (cmp > 0) break; 253 | else if (compare(node.key, low) >= 0) { 254 | if (fn.call(ctx, node)) return this; // stop if smth is returned 255 | } 256 | node = node.right; 257 | } 258 | } 259 | return this; 260 | } 261 | 262 | /** 263 | * Returns all keys in order 264 | */ 265 | keys(): K[] { 266 | let current = this._root; 267 | const s: AVLNode[] = []; 268 | const r: K[] = []; 269 | let done = false; 270 | 271 | while (!done) { 272 | if (current) { 273 | s.push(current); 274 | current = current.left; 275 | } else { 276 | if (s.length > 0) { 277 | current = s.pop()!; 278 | r.push(current.key); 279 | current = current.right; 280 | } else done = true; 281 | } 282 | } 283 | return r; 284 | } 285 | 286 | /** 287 | * Returns `data` fields of all nodes in order. 288 | */ 289 | values(): V[] { 290 | let current = this._root; 291 | const s: AVLNode[] = []; 292 | const r: V[] = []; 293 | let done = false; 294 | 295 | while (!done) { 296 | if (current) { 297 | s.push(current); 298 | current = current.left; 299 | } else { 300 | if (s.length > 0) { 301 | current = s.pop()!; 302 | r.push(current.data!); 303 | current = current.right; 304 | } else done = true; 305 | } 306 | } 307 | return r; 308 | } 309 | 310 | /** 311 | * Returns node at given index 312 | */ 313 | at(index: number) { 314 | // removed after a consideration, more misleading than useful 315 | // index = index % this.size; 316 | // if (index < 0) index = this.size - index; 317 | 318 | let current = this._root; 319 | const s: AVLNode[] = []; 320 | let done = false; 321 | let i = 0; 322 | 323 | while (!done) { 324 | if (current) { 325 | s.push(current); 326 | current = current.left; 327 | } else { 328 | if (s.length > 0) { 329 | current = s.pop()!; 330 | if (i === index) return current; 331 | i++; 332 | current = current.right; 333 | } else done = true; 334 | } 335 | } 336 | return null; 337 | } 338 | 339 | /** 340 | * Returns node with the minimum key 341 | */ 342 | minNode() { 343 | let node = this._root; 344 | if (!node) return null; 345 | while (node.left) node = node.left; 346 | return node; 347 | } 348 | 349 | /** 350 | * Returns node with the max key 351 | */ 352 | maxNode() { 353 | let node = this._root; 354 | if (!node) return null; 355 | while (node.right) node = node.right; 356 | return node; 357 | } 358 | 359 | /** 360 | * Min key 361 | */ 362 | min() { 363 | let node = this._root; 364 | if (!node) return null; 365 | while (node.left) node = node.left; 366 | return node.key; 367 | } 368 | 369 | /** 370 | * Max key 371 | */ 372 | max() { 373 | let node = this._root; 374 | if (!node) return null; 375 | while (node.right) node = node.right; 376 | return node.key; 377 | } 378 | 379 | /** 380 | * @return {boolean} true/false 381 | */ 382 | isEmpty() { 383 | return this._root === null; 384 | } 385 | 386 | /** 387 | * Removes and returns the node with smallest key 388 | */ 389 | pop() { 390 | let node = this._root; 391 | let returnValue: AVLNode | null = null; 392 | if (node) { 393 | while (node.left) node = node.left; 394 | returnValue = { key: node.key, data: node.data } as AVLNode; 395 | this.remove(node.key); 396 | } 397 | return returnValue; 398 | } 399 | 400 | /** 401 | * Removes and returns the node with highest key 402 | */ 403 | popMax() { 404 | let node = this._root; 405 | let returnValue: AVLNode | null = null; 406 | if (node) { 407 | while (node.right) node = node.right; 408 | returnValue = { key: node.key, data: node.data } as AVLNode; 409 | this.remove(node.key); 410 | } 411 | return returnValue; 412 | } 413 | 414 | /** 415 | * Find node by key 416 | */ 417 | find(key: K) { 418 | const root = this._root; 419 | // if (root === null) return null; 420 | // if (key === root.key) return root; 421 | 422 | let subtree = root; 423 | const compare = this._comparator; 424 | while (subtree) { 425 | const cmp = compare(key, subtree.key); 426 | if (cmp === 0) return subtree; 427 | else if (cmp < 0) subtree = subtree.left; 428 | else subtree = subtree.right; 429 | } 430 | 431 | return null; 432 | } 433 | 434 | /** 435 | * Insert a node into the tree 436 | */ 437 | insert(key: K, data?: V) { 438 | if (!this._root) { 439 | this._root = { 440 | parent: null, 441 | left: null, 442 | right: null, 443 | balanceFactor: 0, 444 | key, 445 | data, 446 | }; 447 | this._size++; 448 | return this._root; 449 | } 450 | 451 | const compare = this._comparator; 452 | let node: AVLNode | null = this._root; 453 | let parent: AVLNode | null = null; 454 | let cmp = 0; 455 | 456 | if (this._noDuplicates) { 457 | while (node) { 458 | cmp = compare(key, node.key); 459 | parent = node; 460 | if (cmp === 0) return null; 461 | else if (cmp < 0) node = node.left; 462 | else node = node.right; 463 | } 464 | } else { 465 | while (node) { 466 | cmp = compare(key, node.key); 467 | parent = node; 468 | if (cmp <= 0) node = node.left; //return null; 469 | else node = node.right; 470 | } 471 | } 472 | 473 | const newNode = { 474 | left: null, 475 | right: null, 476 | balanceFactor: 0, 477 | parent, 478 | key, 479 | data, 480 | } as AVLNode; 481 | let newRoot: AVLNode | null = null; 482 | if (cmp <= 0) parent!.left = newNode; 483 | else parent!.right = newNode; 484 | 485 | while (parent) { 486 | cmp = compare(parent.key, key); 487 | if (cmp < 0) parent.balanceFactor -= 1; 488 | else parent.balanceFactor += 1; 489 | 490 | if (parent.balanceFactor === 0) break; 491 | else if (parent.balanceFactor < -1) { 492 | // inlined 493 | //var newRoot = rightBalance(parent); 494 | if (parent.right!.balanceFactor === 1) rotateRight(parent.right!); 495 | newRoot = rotateLeft(parent); 496 | 497 | if (parent === this._root) this._root = newRoot; 498 | break; 499 | } else if (parent.balanceFactor > 1) { 500 | // inlined 501 | // var newRoot = leftBalance(parent); 502 | if (parent.left!.balanceFactor === -1) rotateLeft(parent.left!); 503 | newRoot = rotateRight(parent); 504 | 505 | if (parent === this._root) this._root = newRoot; 506 | break; 507 | } 508 | parent = parent.parent; 509 | } 510 | 511 | this._size++; 512 | return newNode; 513 | } 514 | 515 | /** 516 | * Removes the node from the tree. If not found, returns null. 517 | */ 518 | remove(key: K) { 519 | if (!this._root) return null; 520 | 521 | let node: AVLNode | null = this._root; 522 | const compare = this._comparator; 523 | let cmp = 0; 524 | 525 | while (node) { 526 | cmp = compare(key, node.key); 527 | if (cmp === 0) break; 528 | else if (cmp < 0) node = node.left; 529 | else node = node.right; 530 | } 531 | if (!node) return null; 532 | 533 | const returnValue = node.key; 534 | let max: AVLNode, min: AVLNode; 535 | 536 | if (node.left) { 537 | max = node.left; 538 | 539 | while (max.left || max.right) { 540 | while (max.right) max = max.right; 541 | 542 | node.key = max.key; 543 | node.data = max.data; 544 | if (max.left) { 545 | node = max; 546 | max = max.left; 547 | } 548 | } 549 | 550 | node.key = max.key; 551 | node.data = max.data; 552 | node = max; 553 | } 554 | 555 | if (node.right) { 556 | min = node.right; 557 | 558 | while (min.left || min.right) { 559 | while (min.left) min = min.left; 560 | 561 | node.key = min.key; 562 | node.data = min.data; 563 | if (min.right) { 564 | node = min; 565 | min = min.right; 566 | } 567 | } 568 | 569 | node.key = min.key; 570 | node.data = min.data; 571 | node = min; 572 | } 573 | 574 | let parent = node.parent; 575 | let pp = node; 576 | let newRoot: AVLNode; 577 | 578 | while (parent) { 579 | if (parent.left === pp) parent.balanceFactor -= 1; 580 | else parent.balanceFactor += 1; 581 | 582 | if (parent.balanceFactor < -1) { 583 | // inlined 584 | //var newRoot = rightBalance(parent); 585 | if (parent.right!.balanceFactor === 1) rotateRight(parent.right!); 586 | newRoot = rotateLeft(parent); 587 | 588 | if (parent === this._root) this._root = newRoot; 589 | parent = newRoot; 590 | } else if (parent.balanceFactor > 1) { 591 | // inlined 592 | // var newRoot = leftBalance(parent); 593 | if (parent.left!.balanceFactor === -1) rotateLeft(parent.left!); 594 | newRoot = rotateRight(parent); 595 | 596 | if (parent === this._root) this._root = newRoot; 597 | parent = newRoot; 598 | } 599 | 600 | if (parent.balanceFactor === -1 || parent.balanceFactor === 1) break; 601 | 602 | pp = parent; 603 | parent = parent.parent; 604 | } 605 | 606 | if (node.parent) { 607 | if (node.parent.left === node) node.parent.left = null; 608 | else node.parent.right = null; 609 | } 610 | 611 | if (node === this._root) this._root = null; 612 | 613 | this._size--; 614 | return returnValue; 615 | } 616 | 617 | /** 618 | * Bulk-load items 619 | */ 620 | load(keys: K[] = [], values: V[] = [], presort?: boolean) { 621 | if (this._size !== 0) throw new Error("bulk-load: tree is not empty"); 622 | const size = keys.length; 623 | if (presort) sort(keys, values, 0, size - 1, this._comparator); 624 | this._root = loadRecursive(null, keys, values, 0, size); 625 | markBalance(this._root); 626 | this._size = size; 627 | return this; 628 | } 629 | 630 | /** 631 | * Returns true if the tree is balanced 632 | */ 633 | isBalanced() { 634 | return isBalanced(this._root); 635 | } 636 | 637 | /** 638 | * String representation of the tree - primitive horizontal print-out 639 | */ 640 | toString(printNode?: NodePrinter) { 641 | return print(this._root, printNode); 642 | } 643 | } 644 | 645 | export { AVLTree as Tree }; 646 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface AVLNode { 2 | parent: AVLNode | null; 3 | left: AVLNode | null; 4 | right: AVLNode | null; 5 | balanceFactor: number; 6 | key: K; 7 | data?: V; 8 | } 9 | 10 | /** Callback for comparator */ 11 | export type Comparator = (a: K, b: K) => number | 1 | 0 | -1; 12 | export type Visitor = (node: AVLNode, i: number) => void; 13 | export type NodeCallback = ( 14 | this: T | undefined, 15 | node: AVLNode 16 | ) => void | boolean; 17 | export type NodePrinter = (node: AVLNode) => string; 18 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import type { AVLNode, NodePrinter } from "./types"; 2 | import { Comparator } from "bintrees"; 3 | 4 | /** 5 | * Prints tree horizontally 6 | */ 7 | export function print( 8 | root: AVLNode | null, 9 | printNode: NodePrinter = (n) => n.key as string 10 | ) { 11 | const out: string[] = []; 12 | row(root, "", true, (v) => out.push(v), printNode); 13 | return out.join(""); 14 | } 15 | 16 | /** 17 | * Prints level of the tree 18 | */ 19 | function row( 20 | root: AVLNode | null, 21 | prefix: string, 22 | isTail: boolean, 23 | out: (str: string) => void, 24 | printNode: NodePrinter 25 | ) { 26 | if (root) { 27 | out(`${prefix}${isTail ? "└── " : "├── "}${printNode(root)}\n`); 28 | const indent = prefix + (isTail ? " " : "│ "); 29 | if (root.left) row(root.left, indent, false, out, printNode); 30 | if (root.right) row(root.right, indent, true, out, printNode); 31 | } 32 | } 33 | 34 | /** 35 | * Is the tree balanced (none of the subtrees differ in height by more than 1) 36 | */ 37 | export function isBalanced(root: AVLNode | null): boolean { 38 | if (root === null) return true; // If node is empty then return true 39 | 40 | // Get the height of left and right sub trees 41 | const lh = height(root.left); 42 | const rh = height(root.right); 43 | 44 | if (Math.abs(lh - rh) <= 1 && isBalanced(root.left) && isBalanced(root.right)) 45 | return true; 46 | 47 | // If we reach here then tree is not height-balanced 48 | return false; 49 | } 50 | 51 | /** 52 | * The function Compute the 'height' of a tree. 53 | * Height is the number of nodes along the longest path 54 | * from the root node down to the farthest leaf node. 55 | */ 56 | function height(node: AVLNode | null): number { 57 | return node ? 1 + Math.max(height(node.left), height(node.right)) : 0; 58 | } 59 | 60 | export function loadRecursive( 61 | parent: AVLNode | null, 62 | keys: K[], 63 | values: V[], 64 | start: number, 65 | end: number 66 | ) { 67 | const size = end - start; 68 | if (size > 0) { 69 | const middle = start + Math.floor(size / 2); 70 | const key = keys[middle]; 71 | const data = values[middle]; 72 | const node = { key, data, parent } as AVLNode; 73 | node.left = loadRecursive(node, keys, values, start, middle); 74 | node.right = loadRecursive(node, keys, values, middle + 1, end); 75 | return node; 76 | } 77 | return null; 78 | } 79 | 80 | export function markBalance(node: AVLNode | null): number { 81 | if (node === null) return 0; 82 | const lh = markBalance(node.left); 83 | const rh = markBalance(node.right); 84 | 85 | node.balanceFactor = lh - rh; 86 | return Math.max(lh, rh) + 1; 87 | } 88 | 89 | export function sort( 90 | keys: K[], 91 | values: V[], 92 | left: number, 93 | right: number, 94 | compare: Comparator 95 | ) { 96 | if (left >= right) return; 97 | 98 | const pivot = keys[(left + right) >> 1]; 99 | let i = left - 1; 100 | let j = right + 1; 101 | 102 | while (true) { 103 | do i++; 104 | while (compare(keys[i], pivot) < 0); 105 | do j--; 106 | while (compare(keys[j], pivot) > 0); 107 | if (i >= j) break; 108 | 109 | const tmpk = keys[i]; 110 | keys[i] = keys[j]; 111 | keys[j] = tmpk; 112 | 113 | const tmpv = values[i]; 114 | values[i] = values[j]; 115 | values[j] = tmpv; 116 | } 117 | 118 | sort(keys, values, left, j, compare); 119 | sort(keys, values, j + 1, right, compare); 120 | } 121 | -------------------------------------------------------------------------------- /tests/balance.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("balance", () => { 5 | it("should be balance after in order insert", () => { 6 | const tree = new Tree(); 7 | tree.insert(1); 8 | tree.insert(3); 9 | tree.insert(2); 10 | tree.insert(4); 11 | tree.insert(0); 12 | tree.insert(-10); 13 | tree.insert(20); 14 | 15 | // console.log(tree.toString()); 16 | 17 | assert.isTrue(tree.isBalanced()); 18 | }); 19 | 20 | it("should be balance after random insert", () => { 21 | const tree = new Tree(); 22 | const min = -100, 23 | max = 100; 24 | 25 | for (let i = 0; i < 20; i++) { 26 | tree.insert(min + Math.floor((max - min) * Math.random())); 27 | } 28 | 29 | console.log(tree.toString()); 30 | 31 | // console.log(Tree.verifyBalanceFactor(tree._root)); 32 | assert.isTrue(tree.isBalanced()); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/compare.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | function shuffle(array: T[]) { 5 | let currentIndex = array.length, 6 | temporaryValue, 7 | randomIndex; 8 | while (0 !== currentIndex) { 9 | randomIndex = Math.floor(Math.random() * currentIndex); 10 | currentIndex -= 1; 11 | temporaryValue = array[currentIndex]; 12 | array[currentIndex] = array[randomIndex]; 13 | array[randomIndex] = temporaryValue; 14 | } 15 | return array; 16 | } 17 | 18 | describe("custom comparator", () => { 19 | it("should function correctly given a non-reverse customCompare", () => { 20 | const tree = new Tree((a, b) => b - a); 21 | tree.insert(2); 22 | tree.insert(1); 23 | tree.insert(3); 24 | assert.equal(tree.size, 3); 25 | assert.equal(tree.min(), 3); 26 | assert.equal(tree.max(), 1); 27 | tree.remove(3); 28 | assert.equal(tree.size, 2); 29 | assert.equal(tree.root!.key, 2); 30 | assert.equal(tree.root!.left, null); 31 | assert.equal(tree.root!.right!.key, 1); 32 | }); 33 | 34 | it("should support custom keys", () => { 35 | type CustomKey = { value: number }; 36 | const comparator = (a: CustomKey, b: CustomKey) => a.value - b.value; 37 | const tree = new Tree(comparator); 38 | const objects = new Array(10).fill(0).map((n, i) => { 39 | return { value: i, data: Math.pow(i, 2) }; 40 | }); 41 | shuffle(objects); 42 | 43 | objects.forEach((o) => tree.insert(o)); 44 | 45 | assert.deepEqual( 46 | tree.keys().map((k) => k.value), 47 | objects 48 | .slice() 49 | .sort(comparator) 50 | .map((k) => k.value) 51 | ); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /tests/contains.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("contains check", () => { 5 | it("should return false if the tree is empty", () => { 6 | const tree = new Tree(); 7 | assert.isFalse(tree.contains(1)); 8 | }); 9 | 10 | it("should return whether the tree contains a node", () => { 11 | const tree = new Tree(); 12 | assert.isFalse(tree.contains(1)); 13 | assert.isFalse(tree.contains(2)); 14 | assert.isFalse(tree.contains(3)); 15 | tree.insert(3); 16 | tree.insert(1); 17 | tree.insert(2); 18 | assert.isTrue(tree.contains(1)); 19 | assert.isTrue(tree.contains(2)); 20 | assert.isTrue(tree.contains(3)); 21 | }); 22 | 23 | it("should return false when the expected parent has no children", () => { 24 | const tree = new Tree(); 25 | tree.insert(2); 26 | assert.isFalse(tree.contains(1)); 27 | assert.isFalse(tree.contains(3)); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/duplicate.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("Duplicate keys", () => { 5 | it("should allow inserting of duplicate key", () => { 6 | const tree = new Tree(); 7 | const values = [2, 12, 1, -6, 1]; 8 | 9 | values.forEach((v) => { 10 | tree.insert(v); 11 | assert.isTrue(tree.isBalanced()); 12 | }); 13 | 14 | assert.deepEqual(tree.keys(), [-6, 1, 1, 2, 12]); 15 | assert.equal(tree.size, 5); 16 | assert.isTrue(tree.isBalanced()); 17 | }); 18 | 19 | it("should allow multiple duplicate keys in a row", () => { 20 | const tree = new Tree(); 21 | const values = [2, 12, 1, 1, -6, 2, 1, 1, 13]; 22 | 23 | values.forEach((v) => { 24 | tree.insert(v); 25 | assert.isTrue(tree.isBalanced()); 26 | }); 27 | 28 | assert.deepEqual(tree.keys(), [-6, 1, 1, 1, 1, 2, 2, 12, 13]); 29 | assert.equal(tree.size, 9); 30 | assert.isTrue(tree.isBalanced()); 31 | }); 32 | 33 | it("should remove from a tree with duplicate keys correctly", () => { 34 | const tree = new Tree(); 35 | const values = [2, 12, 1, 1, -6, 1, 1]; 36 | 37 | values.forEach((v) => tree.insert(v)); 38 | 39 | let size = tree.size; 40 | for (let i = 0; i < 4; i++) { 41 | tree.remove(1); 42 | 43 | if (i < 3) assert.isTrue(tree.contains(1)); 44 | assert.isTrue(tree.isBalanced()); 45 | assert.equal(tree.size, --size); 46 | } 47 | 48 | assert.isFalse(tree.contains(1)); 49 | assert.isTrue(tree.isBalanced()); 50 | }); 51 | 52 | it("should remove from a tree with multiple duplicate keys correctly", () => { 53 | const tree = new Tree(); 54 | const values = [2, 12, 1, 1, -6, 1, 1, 2, 0, 2]; 55 | 56 | values.forEach((v) => tree.insert(v)); 57 | 58 | let size = tree.size; 59 | while (!tree.isEmpty()) { 60 | tree.pop(); 61 | 62 | assert.isTrue(tree.isBalanced()); 63 | assert.equal(tree.size, --size); 64 | } 65 | }); 66 | 67 | it("should disallow duplicates if noDuplicates is set", () => { 68 | const tree = new Tree(undefined, true); 69 | const values = [2, 12, 1, -6, 1]; 70 | 71 | values.forEach((v) => { 72 | tree.insert(v); 73 | assert.isTrue(tree.isBalanced()); 74 | }); 75 | 76 | assert.deepEqual(tree.keys(), [-6, 1, 2, 12]); 77 | assert.equal(tree.size, 4); 78 | assert.isTrue(tree.isBalanced()); 79 | }); 80 | }); 81 | -------------------------------------------------------------------------------- /tests/empty.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("empty check", () => { 5 | it("should return whether the tree is empty", () => { 6 | const tree = new Tree(); 7 | 8 | assert.isTrue(tree.isEmpty()); 9 | tree.insert(1); 10 | assert.isFalse(tree.isEmpty()); 11 | tree.remove(1); 12 | assert.isTrue(tree.isEmpty()); 13 | }); 14 | 15 | it("should clear the tree", () => { 16 | const tree = new Tree(); 17 | tree.insert(1); 18 | tree.insert(2); 19 | tree.insert(3); 20 | tree.insert(4); 21 | 22 | tree.clear(); 23 | assert.isTrue(tree.isEmpty()); 24 | assert.equal(tree.size, 0); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/find.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("find", () => { 5 | it("should return key as the result of search", () => { 6 | const tree = new Tree(); 7 | assert.equal(tree.find(1), null); 8 | assert.equal(tree.find(2), null); 9 | assert.equal(tree.find(3), null); 10 | tree.insert(1, 4); 11 | tree.insert(2, 5); 12 | tree.insert(3, 6); 13 | assert.equal(tree.find(1)!.data, 4); 14 | assert.equal(tree.find(2)!.data, 5); 15 | assert.equal(tree.find(3)!.data, 6); 16 | assert.isNull(tree.find(8)); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/insert.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { AVLTree as Tree } from "../src/"; 3 | 4 | describe("insert", () => { 5 | it("should return the size of the tree", () => { 6 | const tree = new Tree(); 7 | tree.insert(1); 8 | tree.insert(2); 9 | tree.insert(3); 10 | tree.insert(4); 11 | tree.insert(5); 12 | assert.equal(tree.size, 5); 13 | }); 14 | 15 | /** 16 | * c 17 | * / \ _b_ 18 | * b z / \ 19 | * / \ -> a c 20 | * a y / \ / \ 21 | * / \ w x y z 22 | * w x 23 | */ 24 | it("should correctly balance the left left case", () => { 25 | const tree = new Tree(); 26 | tree.insert(3); 27 | tree.insert(2); 28 | tree.insert(1); 29 | assert.equal(tree.root!.key, 2); 30 | }); 31 | 32 | /** 33 | * c 34 | * / \ _b_ 35 | * a z / \ 36 | * / \ -> a c 37 | * w b / \ / \ 38 | * / \ w x y z 39 | * x y 40 | */ 41 | it("should correctly balance the left right case", () => { 42 | const tree = new Tree(); 43 | tree.insert(3); 44 | tree.insert(1); 45 | tree.insert(2); 46 | assert.equal(tree.root!.key, 2); 47 | }); 48 | 49 | /** 50 | * a 51 | * / \ _b_ 52 | * w b / \ 53 | * / \ -> a c 54 | * x c / \ / \ 55 | * / \ w x y z 56 | * y z 57 | */ 58 | it("should correctly balance the right right case", () => { 59 | const tree = new Tree(); 60 | tree.insert(1); 61 | tree.insert(2); 62 | tree.insert(3); 63 | assert.equal(tree.root!.key, 2); 64 | }); 65 | 66 | /** 67 | * a 68 | * / \ _b_ 69 | * w c / \ 70 | * / \ -> a c 71 | * b z / \ / \ 72 | * / \ w x y z 73 | * x y 74 | */ 75 | it("should correctly balance the right left case", () => { 76 | const tree = new Tree(); 77 | tree.insert(1); 78 | tree.insert(3); 79 | tree.insert(2); 80 | assert.equal(tree.root!.key, 2); 81 | }); 82 | 83 | it("should allow bulk-insert", () => { 84 | const tree = new Tree(); 85 | const keys = [1, 2, 3, 4]; 86 | const values = [4, 3, 2, 1]; 87 | tree.load(keys, values, true); 88 | 89 | assert.deepEqual(tree.keys(), keys); 90 | assert.deepEqual(tree.values(), values); 91 | }); 92 | 93 | it("should allow bulk-insert without values", () => { 94 | const tree = new Tree(); 95 | const keys = [1, 2, 3, 4, 5, 6, 7, 8]; 96 | tree.load(keys, undefined, true); 97 | 98 | assert.deepEqual(tree.keys(), keys); 99 | assert.deepEqual( 100 | tree.values(), 101 | keys.map(() => undefined) 102 | ); 103 | 104 | //assert.isTrue(tree.isBalanced()); 105 | }); 106 | 107 | it("should mark balance properly after bulk-load", () => { 108 | const tree = new Tree(); 109 | const keys = [1, 2, 3, 4, 5, 6, 7, 8]; 110 | tree.load(keys, undefined, true); 111 | 112 | //tree.insert(0); 113 | 114 | assert.isTrue(tree.isBalanced()); 115 | }); 116 | }); 117 | -------------------------------------------------------------------------------- /tests/keys-values.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { AVLTree as Tree } from "../src/"; 3 | 4 | describe("Keys and values", () => { 5 | it("should return sorted keys", () => { 6 | const t = new Tree((a, b) => b - a); 7 | t.insert(5); 8 | t.insert(-10); 9 | t.insert(0); 10 | t.insert(33); 11 | t.insert(2); 12 | 13 | assert.deepEqual(t.keys(), [33, 5, 2, 0, -10]); 14 | }); 15 | 16 | it("should return sorted keys", () => { 17 | const t = new Tree(); 18 | t.insert(5); 19 | t.insert(-10); 20 | t.insert(0); 21 | t.insert(33); 22 | t.insert(2); 23 | 24 | assert.deepEqual(t.keys(), [-10, 0, 2, 5, 33]); 25 | }); 26 | 27 | it("should return sorted values", () => { 28 | const t = new Tree(); 29 | t.insert(5, "D"); 30 | t.insert(-10, "A"); 31 | t.insert(0, "B"); 32 | t.insert(33, "E"); 33 | t.insert(2, "C"); 34 | 35 | assert.deepEqual(t.keys(), [-10, 0, 2, 5, 33]); 36 | assert.deepEqual(t.values(), ["A", "B", "C", "D", "E"]); 37 | }); 38 | 39 | it("should return sorted values", () => { 40 | const t = new Tree((a, b) => b - a); 41 | t.insert(5, "D"); 42 | t.insert(-10, "A"); 43 | t.insert(0, "B"); 44 | t.insert(33, "E"); 45 | t.insert(2, "C"); 46 | 47 | assert.deepEqual(t.keys(), [33, 5, 2, 0, -10]); 48 | assert.deepEqual(t.values(), ["E", "D", "C", "B", "A"]); 49 | }); 50 | 51 | it("should return sorted values after bulk insert", () => { 52 | const t = new Tree(); 53 | t.load([5, -10, 0, 33, 2], ["D", "A", "B", "E", "C"], true); 54 | 55 | assert.deepEqual(t.keys(), [-10, 0, 2, 5, 33]); 56 | assert.deepEqual(t.values(), ["A", "B", "C", "D", "E"]); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /tests/min-max.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("find min and max", () => { 5 | it("should return the maximum key in the tree", () => { 6 | const tree = new Tree(); 7 | tree.insert(3); 8 | tree.insert(5); 9 | tree.insert(1); 10 | tree.insert(4); 11 | tree.insert(2); 12 | assert.equal(tree.max(), 5); 13 | }); 14 | 15 | it("should return null for max if the tree is empty", () => { 16 | const tree = new Tree(); 17 | assert.isNull(tree.max()); 18 | }); 19 | 20 | it("should return the minimum key in the tree", () => { 21 | const tree = new Tree(); 22 | tree.insert(5); 23 | tree.insert(3); 24 | tree.insert(1); 25 | tree.insert(4); 26 | tree.insert(2); 27 | assert.equal(tree.min(), 1); 28 | }); 29 | 30 | it("should return the max node", () => { 31 | const tree = new Tree(); 32 | tree.insert(3); 33 | tree.insert(5, 10); 34 | tree.insert(1); 35 | tree.insert(4); 36 | tree.insert(2); 37 | const node = tree.maxNode()!; 38 | assert.equal(node.key, 5); 39 | assert.equal(node.data, 10); 40 | }); 41 | 42 | it("should return null for maxNode if the tree is empty", () => { 43 | const tree = new Tree(); 44 | assert.isNull(tree.maxNode()); 45 | }); 46 | 47 | it("should return the min node", () => { 48 | const tree = new Tree(); 49 | tree.insert(5); 50 | tree.insert(3); 51 | tree.insert(1, 20); 52 | tree.insert(4); 53 | tree.insert(2); 54 | const node = tree.minNode()!; 55 | assert.equal(node.key, 1); 56 | assert.equal(node.data, 20); 57 | }); 58 | 59 | it("should return null for min if the tree is empty", () => { 60 | const tree = new Tree(); 61 | assert.isNull(tree.min()); 62 | }); 63 | 64 | it("should support removing min node", () => { 65 | const tree = new Tree(); 66 | tree.insert(5); 67 | tree.insert(3); 68 | tree.insert(1); 69 | tree.insert(4); 70 | tree.insert(2); 71 | assert.equal(tree.pop()!.key, 1); 72 | }); 73 | 74 | it("should support removing max node", () => { 75 | const tree = new Tree(); 76 | tree.insert(5); 77 | tree.insert(3); 78 | tree.insert(1); 79 | tree.insert(4); 80 | tree.insert(2); 81 | assert.equal(tree.popMax()!.key, 5); 82 | }); 83 | 84 | it("should return null for minNode if the tree is empty", () => { 85 | const tree = new Tree(); 86 | assert.isNull(tree.minNode()); 87 | }); 88 | }); 89 | -------------------------------------------------------------------------------- /tests/remove.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("remove", () => { 5 | it("should not change the size of a tree with no root", () => { 6 | const tree = new Tree(); 7 | tree.remove(1); 8 | assert.equal(tree.size, 0); 9 | }); 10 | 11 | it("should remove a single key", () => { 12 | const tree = new Tree(); 13 | tree.insert(1); 14 | tree.remove(1); 15 | assert.isTrue(tree.isEmpty()); 16 | }); 17 | 18 | /** 19 | * _4_ _2_ 20 | * / \ / \ 21 | * 2 6 -> remove(6) -> 1 4 22 | * / \ / 23 | * 1 3 3 24 | */ 25 | it("should correctly balance the left left case", () => { 26 | const tree = new Tree(); 27 | tree.insert(4); 28 | tree.insert(2); 29 | tree.insert(6); 30 | tree.insert(3); 31 | tree.insert(5); 32 | tree.insert(1); 33 | tree.insert(7); 34 | tree.remove(7); 35 | tree.remove(5); 36 | tree.remove(6); 37 | assert.equal(tree.root!.key, 2); 38 | assert.equal(tree.root!.left!.key, 1); 39 | assert.equal(tree.root!.right!.key, 4); 40 | assert.equal(tree.root!.right!.left!.key, 3); 41 | }); 42 | 43 | /** 44 | * _4_ _6_ 45 | * / \ / \ 46 | * 2 6 -> remove(2) -> 4 7 47 | * / \ \ 48 | * 5 7 5 49 | */ 50 | it("should correctly balance the right right case", () => { 51 | const tree = new Tree(); 52 | tree.insert(4); 53 | tree.insert(2); 54 | tree.insert(6); 55 | tree.insert(3); 56 | tree.insert(5); 57 | tree.insert(1); 58 | tree.insert(7); 59 | tree.remove(1); 60 | tree.remove(3); 61 | tree.remove(2); 62 | assert.equal(tree.root!.key, 6); 63 | assert.equal(tree.root!.left!.key, 4); 64 | assert.equal(tree.root!.left!.right!.key, 5); 65 | assert.equal(tree.root!.right!.key, 7); 66 | }); 67 | 68 | /** 69 | * _6_ _4_ 70 | * / \ / \ 71 | * 2 7 -> remove(8) -> 2 6 72 | * / \ \ / \ / \ 73 | * 1 4 8 1 3 5 7 74 | * / \ 75 | * 3 5 76 | */ 77 | it("should correctly balance the left right case", () => { 78 | const tree = new Tree(); 79 | tree.insert(6); 80 | tree.insert(2); 81 | tree.insert(7); 82 | tree.insert(1); 83 | tree.insert(8); 84 | tree.insert(4); 85 | tree.insert(3); 86 | tree.insert(5); 87 | tree.remove(8); 88 | assert.equal(tree.root!.key, 4); 89 | assert.equal(tree.root!.left!.key, 2); 90 | assert.equal(tree.root!.left!.left!.key, 1); 91 | assert.equal(tree.root!.left!.right!.key, 3); 92 | assert.equal(tree.root!.right!.key, 6); 93 | assert.equal(tree.root!.right!.left!.key, 5); 94 | assert.equal(tree.root!.right!.right!.key, 7); 95 | }); 96 | 97 | /** 98 | * _3_ _5_ 99 | * / \ / \ 100 | * 2 7 -> remove(1) -> 3 7 101 | * / / \ / \ / \ 102 | * 1 5 8 2 4 6 8 103 | * / \ 104 | * 4 6 105 | */ 106 | it("should correctly balance the right left case", () => { 107 | const tree = new Tree(); 108 | tree.insert(3); 109 | tree.insert(2); 110 | tree.insert(7); 111 | tree.insert(1); 112 | tree.insert(8); 113 | tree.insert(5); 114 | tree.insert(4); 115 | tree.insert(6); 116 | tree.remove(1); 117 | assert.equal(tree.root!.key, 5); 118 | assert.equal(tree.root!.left!.key, 3); 119 | assert.equal(tree.root!.left!.left!.key, 2); 120 | assert.equal(tree.root!.left!.right!.key, 4); 121 | assert.equal(tree.root!.right!.key, 7); 122 | assert.equal(tree.root!.right!.left!.key, 6); 123 | assert.equal(tree.root!.right!.right!.key, 8); 124 | }); 125 | 126 | it("should take the right child if the left does not exist", () => { 127 | const tree = new Tree(); 128 | tree.insert(1); 129 | tree.insert(2); 130 | tree.remove(1); 131 | assert.equal(tree.root!.key, 2); 132 | }); 133 | 134 | it("should take the left child if the right does not exist", () => { 135 | const tree = new Tree(); 136 | tree.insert(2); 137 | tree.insert(1); 138 | tree.remove(2); 139 | assert.equal(tree.root!.key, 1); 140 | }); 141 | 142 | it("should get the right child if the node has 2 leaf children", () => { 143 | const tree = new Tree(); 144 | tree.insert(2); 145 | tree.insert(1); 146 | tree.insert(3); 147 | tree.remove(2); 148 | assert.equal(tree.root!.key, 1); 149 | }); 150 | 151 | it("should get the in-order successor if the node has both children", () => { 152 | const tree = new Tree(); 153 | tree.insert(2); 154 | tree.insert(1); 155 | tree.insert(4); 156 | tree.insert(3); 157 | tree.insert(5); 158 | tree.remove(2); 159 | assert.equal(tree.root!.key, 4); 160 | }); 161 | }); 162 | -------------------------------------------------------------------------------- /tests/traversal.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, assert } from "vitest"; 2 | import { Tree } from "../src/"; 3 | 4 | describe("traversal check", () => { 5 | it("should traverse the tree in order", () => { 6 | const tree = new Tree(); 7 | tree.insert(3); 8 | tree.insert(1); 9 | tree.insert(0); 10 | tree.insert(2); 11 | 12 | tree.forEach((n, i) => assert.equal(n.key, i)); 13 | }); 14 | 15 | it("should find predecessor for the node", () => { 16 | const tree = new Tree(); 17 | for (let i = 0; i < 10; i++) tree.insert(i); 18 | 19 | for (let i = 1; i < 10; i++) { 20 | assert.strictEqual(tree.prev(tree.find(i)!), tree.find(i - 1)); 21 | } 22 | }); 23 | 24 | it("should find successor for a node", () => { 25 | const tree = new Tree(); 26 | for (let i = 0; i < 10; i++) tree.insert(i); 27 | 28 | for (let i = 0; i < 9; i++) { 29 | assert.strictEqual(tree.next(tree.find(i)!), tree.find(i + 1)); 30 | } 31 | }); 32 | 33 | it("should return null for predecessor of the min node", () => { 34 | const tree = new Tree(); 35 | for (let i = 0; i < 10; i++) tree.insert(i); 36 | 37 | let min = tree.minNode()!; 38 | assert.isNull(tree.prev(min)); 39 | tree.remove(min.key); 40 | min = tree.minNode()!; 41 | assert.isNull(tree.prev(min)); 42 | }); 43 | 44 | it("should return null for successor of the max node", () => { 45 | const tree = new Tree(); 46 | for (let i = 0; i < 10; i++) tree.insert(i); 47 | 48 | let max = tree.maxNode()!; 49 | assert.isNull(tree.next(max)); 50 | tree.remove(max.key); 51 | max = tree.maxNode()!; 52 | assert.isNull(tree.next(max)); 53 | }); 54 | 55 | it("should find successor and predecessor for 2-nodes tree", () => { 56 | const tree = new Tree(); 57 | tree.insert(5); 58 | tree.insert(10); 59 | 60 | const min = tree.minNode()!; 61 | assert.equal(min.key, 5); 62 | assert.isNull(tree.prev(min)); 63 | assert.equal(tree.next(min)!.key, 10); 64 | 65 | const max = tree.maxNode()!; 66 | assert.equal(max.key, 10); 67 | assert.isNull(tree.next(max)); 68 | assert.equal(tree.prev(max)!.key, 5); 69 | }); 70 | 71 | it("should be able to get a node by its index", () => { 72 | const tree = new Tree(); 73 | for (let i = 0; i < 10; i++) tree.insert(i); 74 | 75 | for (let i = 0; i < 10; i++) assert.equal(tree.at(i)!.key, i); 76 | 77 | assert.isNull(tree.at(10)); 78 | assert.isNull(tree.at(-1)); 79 | // @ts-expect-error testing invalid type 80 | assert.isNull(tree.at("a")); 81 | }); 82 | 83 | it("should support range walking", () => { 84 | const tree = new Tree(); 85 | for (let i = 0; i < 10; i++) tree.insert(i); 86 | 87 | const arr: number[] = []; 88 | tree.range(3, 8, (n) => { 89 | arr.push(n.key); 90 | }); 91 | assert.deepEqual(arr, [3, 4, 5, 6, 7, 8]); 92 | }); 93 | 94 | it("should support range walking with non-existent low key", () => { 95 | const tree = new Tree(); 96 | for (let i = 0; i < 10; i++) tree.insert(i); 97 | 98 | const arr: number[] = []; 99 | tree.range(-3, 5, (n) => { 100 | arr.push(n.key); 101 | }); 102 | 103 | assert.deepEqual(arr, [0, 1, 2, 3, 4, 5]); 104 | }); 105 | 106 | it("should support range walking with non-existent high key", () => { 107 | const tree = new Tree(); 108 | for (let i = 0; i < 10; i++) tree.insert(i); 109 | 110 | const arr: number[] = []; 111 | tree.range(3, 15, (n) => { 112 | arr.push(n.key); 113 | }); 114 | 115 | assert.deepEqual(arr, [3, 4, 5, 6, 7, 8, 9]); 116 | }); 117 | 118 | it("should support range walking with both keys out of range", () => { 119 | const tree = new Tree(); 120 | for (let i = 0; i < 10; i++) tree.insert(i); 121 | 122 | const arr: number[] = []; 123 | tree.range(10, 20, (n) => { 124 | arr.push(n.key); 125 | }); 126 | 127 | assert.equal(arr.length, 0); 128 | 129 | tree.range(-10, 20, (n) => { 130 | arr.push(n.key); 131 | }); 132 | assert.deepEqual(arr, tree.keys()); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "outDir": "./dist", 5 | "useDefineForClassFields": true, 6 | "module": "commonjs", 7 | "lib": ["ES2021", "DOM", "DOM.Iterable"], 8 | "moduleResolution": "Node", 9 | "strict": true, 10 | "resolveJsonModule": true, 11 | "isolatedModules": false, 12 | "esModuleInterop": true, 13 | "noUnusedLocals": true, 14 | "noUnusedParameters": true, 15 | "noImplicitReturns": true, 16 | "skipLibCheck": true 17 | }, 18 | "include": ["./src/**/*", "./test/**/*"] 19 | } 20 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { resolve } from "path"; 3 | 4 | import { 5 | name as moduleName, 6 | version, 7 | description, 8 | author, 9 | license, 10 | } from "./package.json"; 11 | 12 | const banner = `\ 13 | /** 14 | * ${moduleName} v${version} 15 | * ${description} 16 | * 17 | * @author ${author} 18 | * @license ${license} 19 | * @preserve 20 | */ 21 | `; 22 | 23 | export default defineConfig({ 24 | build: { 25 | target: "es6", 26 | rollupOptions: { 27 | output: { 28 | banner, 29 | }, 30 | }, 31 | lib: { 32 | entry: resolve(__dirname, "src/index.ts"), 33 | name: "avltree", 34 | formats: ["es", "umd", "cjs"], 35 | fileName: (format) => 36 | `index.${{ es: "mjs", umd: "js", cjs: "cjs" }[format]}`, 37 | }, 38 | minify: false, 39 | }, 40 | 41 | test: { 42 | include: ["tests/**/*.test.ts"], 43 | }, 44 | }); 45 | --------------------------------------------------------------------------------