├── .github └── workflows │ └── node.yml ├── .gitignore ├── LICENSE ├── README.md ├── bench.js ├── eslint.config.js ├── index.js ├── package-lock.json ├── package.json ├── rollup.config.js ├── test.js └── tsconfig.json /.github/workflows/node.yml: -------------------------------------------------------------------------------- 1 | name: Node 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: actions/setup-node@v4 9 | - run: npm ci 10 | - run: npm run build 11 | - run: npm test 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | kdbush.js 3 | kdbush.min.js 4 | index.d.ts 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2018, Vladimir Agafonkin 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose 6 | with or without fee is hereby granted, provided that the above copyright notice 7 | and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 11 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 13 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 15 | THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## KDBush 2 | 3 | A very fast static spatial index for 2D points based on a flat KD-tree. 4 | Compared to [RBush](https://github.com/mourner/rbush): 5 | 6 | - **Points only** — no rectangles. 7 | - **Static** — you can't add/remove items after initial indexing. 8 | - **Faster** indexing and search, with lower **memory** footprint. 9 | - Index is stored as a single **array buffer** (so you can [transfer](https://developer.mozilla.org/en-US/docs/Glossary/Transferable_objects) it between threads or store it as a compact file). 10 | 11 | 12 | If you need a static index for rectangles, not only points, see [Flatbush](https://github.com/mourner/flatbush). When indexing points, KDBush has the advantage of taking ~2x less memory than Flatbush. 13 | 14 | [![Build Status](https://github.com/mourner/kdbush/workflows/Node/badge.svg?branch=master)](https://github.com/mourner/kdbush/actions) 15 | [![Simply Awesome](https://img.shields.io/badge/simply-awesome-brightgreen.svg)](https://github.com/mourner/projects) 16 | 17 | ## Usage 18 | 19 | ```js 20 | // initialize KDBush for 1000 items 21 | const index = new KDBush(1000); 22 | 23 | // fill it with 1000 points 24 | for (const {x, y} of items) { 25 | index.add(x, y); 26 | } 27 | 28 | // perform the indexing 29 | index.finish(); 30 | 31 | // make a bounding box query 32 | const foundIds = index.range(minX, minY, maxX, maxY); 33 | 34 | // map ids to original items 35 | const foundItems = foundIds.map(i => items[i]); 36 | 37 | // make a radius query 38 | const neighborIds = index.within(x, y, 5); 39 | 40 | // instantly transfer the index from a worker to the main thread 41 | postMessage(index.data, [index.data]); 42 | 43 | // reconstruct the index from a raw array buffer 44 | const index = KDBush.from(e.data); 45 | ``` 46 | 47 | ## Install 48 | 49 | Install with NPM: `npm install kdbush`, then import as a module: 50 | 51 | ```js 52 | import KDBush from 'kdbush'; 53 | ``` 54 | 55 | Or use as a module directly in the browser with [jsDelivr](https://www.jsdelivr.com/esm): 56 | 57 | ```html 58 | 61 | ``` 62 | 63 | Alternatively, there's a browser bundle with a `KDBush` global variable: 64 | 65 | ```html 66 | 67 | ``` 68 | 69 | ## API 70 | 71 | #### new KDBush(numItems[, nodeSize, ArrayType, ArrayBufferType]) 72 | 73 | Creates an index that will hold a given number of points (`numItems`). Additionally accepts: 74 | 75 | - `nodeSize`: Size of the KD-tree node, `64` by default. Higher means faster indexing but slower search, and vise versa. 76 | - `ArrayType`: Array type to use for storing coordinate values. `Float64Array` by default, but if your coordinates are integer values, `Int32Array` makes the index faster and smaller. 77 | - `ArrayBufferType`: the array buffer type used to store data (`ArrayBuffer` by default); 78 | you may prefer `SharedArrayBuffer` if you want to share the index between threads (multiple `Worker`, `SharedWorker` or `ServiceWorker`). 79 | 80 | #### index.add(x, y) 81 | 82 | Adds a given point to the index. Returns a zero-based, incremental number that represents the newly added point. 83 | 84 | #### index.range(minX, minY, maxX, maxY) 85 | 86 | Finds all items within the given bounding box and returns an array of indices that refer to the order the items were added (the values returned by `index.add(x, y)`). 87 | 88 | #### index.within(x, y, radius) 89 | 90 | Finds all items within a given radius from the query point and returns an array of indices. 91 | 92 | #### `KDBush.from(data)` 93 | 94 | Recreates a KDBush index from raw `ArrayBuffer` or `SharedArrayBuffer` data 95 | (that's exposed as `index.data` on a previously indexed KDBush instance). 96 | Very useful for transferring or sharing indices between threads or storing them in a file. 97 | 98 | ### Properties 99 | 100 | - `data`: array buffer that holds the index. 101 | - `numItems`: number of stored items. 102 | - `nodeSize`: number of items in a KD-tree node. 103 | - `ArrayType`: array type used for internal coordinates storage. 104 | - `IndexArrayType`: array type used for internal item indices storage. 105 | -------------------------------------------------------------------------------- /bench.js: -------------------------------------------------------------------------------- 1 | 2 | import KDBush from './index.js'; 3 | import v8 from 'v8'; 4 | 5 | const randomInt = max => Math.floor(Math.random() * max); 6 | const randomPoint = max => ({x: randomInt(max), y: randomInt(max)}); 7 | const heapSize = () => `${v8.getHeapStatistics().used_heap_size / 1000 } KB`; 8 | 9 | const N = 1000000; 10 | 11 | const coords = new Uint32Array(N * 2); 12 | for (let i = 0; i < N * 2; i++) coords[i] = randomInt(1000); 13 | 14 | console.log(`memory: ${heapSize()}`); 15 | 16 | console.time(`index ${N} points`); 17 | const index = new KDBush(N, 64, Uint32Array); 18 | for (let i = 0; i < coords.length; i += 2) index.add(coords[i], coords[i + 1]); 19 | index.finish(); 20 | console.timeEnd(`index ${N} points`); 21 | console.log(`index size: ${index.data.byteLength.toLocaleString()}`); 22 | 23 | console.log(`memory: ${heapSize()}`); 24 | 25 | console.time('10000 small bbox queries'); 26 | for (let i = 0; i < 10000; i++) { 27 | const p = randomPoint(1000); 28 | index.range(p.x - 1, p.y - 1, p.x + 1, p.y + 1); 29 | } 30 | console.timeEnd('10000 small bbox queries'); 31 | 32 | console.time('10000 small radius queries'); 33 | for (let i = 0; i < 10000; i++) { 34 | const p = randomPoint(1000); 35 | index.within(p.x, p.y, 1); 36 | } 37 | console.timeEnd('10000 small radius queries'); 38 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from 'eslint-config-mourner'; 2 | 3 | export default [ 4 | ...config, 5 | { 6 | ignores: ['kdbush.js', 'kdbush.min.js'] 7 | } 8 | ]; 9 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | const ARRAY_TYPES = [ 3 | Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, 4 | Int32Array, Uint32Array, Float32Array, Float64Array 5 | ]; 6 | 7 | /** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */ 8 | /** @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray */ 9 | 10 | const VERSION = 1; // serialized format version 11 | const HEADER_SIZE = 8; 12 | 13 | export default class KDBush { 14 | 15 | /** 16 | * Creates an index from raw `ArrayBuffer` data. 17 | * @param {ArrayBufferLike} data 18 | */ 19 | static from(data) { 20 | // @ts-expect-error duck typing array buffers 21 | if (!data || data.byteLength === undefined || data.buffer) { 22 | throw new Error('Data must be an instance of ArrayBuffer or SharedArrayBuffer.'); 23 | } 24 | const [magic, versionAndType] = new Uint8Array(data, 0, 2); 25 | if (magic !== 0xdb) { 26 | throw new Error('Data does not appear to be in a KDBush format.'); 27 | } 28 | const version = versionAndType >> 4; 29 | if (version !== VERSION) { 30 | throw new Error(`Got v${version} data when expected v${VERSION}.`); 31 | } 32 | const ArrayType = ARRAY_TYPES[versionAndType & 0x0f]; 33 | if (!ArrayType) { 34 | throw new Error('Unrecognized array type.'); 35 | } 36 | const [nodeSize] = new Uint16Array(data, 2, 1); 37 | const [numItems] = new Uint32Array(data, 4, 1); 38 | 39 | return new KDBush(numItems, nodeSize, ArrayType, undefined, data); 40 | } 41 | 42 | /** 43 | * Creates an index that will hold a given number of items. 44 | * @param {number} numItems 45 | * @param {number} [nodeSize=64] Size of the KD-tree node (64 by default). 46 | * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default). 47 | * @param {ArrayBufferConstructor | SharedArrayBufferConstructor} [ArrayBufferType=ArrayBuffer] The array buffer type used for storage (`ArrayBuffer` by default). 48 | * @param {ArrayBufferLike} [data] (For internal use only) 49 | */ 50 | constructor(numItems, nodeSize = 64, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data) { 51 | if (isNaN(numItems) || numItems < 0) throw new Error(`Unexpected numItems value: ${numItems}.`); 52 | 53 | this.numItems = +numItems; 54 | this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535); 55 | this.ArrayType = ArrayType; 56 | this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array; 57 | 58 | const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType); 59 | const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT; 60 | const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT; 61 | const padCoords = (8 - idsByteSize % 8) % 8; 62 | 63 | if (arrayTypeIndex < 0) { 64 | throw new Error(`Unexpected typed array class: ${ArrayType}.`); 65 | } 66 | 67 | if (data) { // reconstruct an index from a buffer 68 | this.data = data; 69 | // @ts-expect-error TS can't handle SharedArrayBuffer overloads 70 | this.ids = new this.IndexArrayType(data, HEADER_SIZE, numItems); 71 | // @ts-expect-error TS can't handle SharedArrayBuffer overloads 72 | this.coords = new ArrayType(data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2); 73 | this._pos = numItems * 2; 74 | this._finished = true; 75 | 76 | } else { // initialize a new index 77 | const data = this.data = new ArrayBufferType(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords); 78 | // @ts-expect-error TS can't handle SharedArrayBuffer overloads 79 | this.ids = new this.IndexArrayType(data, HEADER_SIZE, numItems); 80 | // @ts-expect-error TS can't handle SharedArrayBuffer overloads 81 | this.coords = new ArrayType(data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2); 82 | this._pos = 0; 83 | this._finished = false; 84 | 85 | // set header 86 | new Uint8Array(data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]); 87 | new Uint16Array(data, 2, 1)[0] = nodeSize; 88 | new Uint32Array(data, 4, 1)[0] = numItems; 89 | } 90 | } 91 | 92 | /** 93 | * Add a point to the index. 94 | * @param {number} x 95 | * @param {number} y 96 | * @returns {number} An incremental index associated with the added item (starting from `0`). 97 | */ 98 | add(x, y) { 99 | const index = this._pos >> 1; 100 | this.ids[index] = index; 101 | this.coords[this._pos++] = x; 102 | this.coords[this._pos++] = y; 103 | return index; 104 | } 105 | 106 | /** 107 | * Perform indexing of the added points. 108 | */ 109 | finish() { 110 | const numAdded = this._pos >> 1; 111 | if (numAdded !== this.numItems) { 112 | throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`); 113 | } 114 | // kd-sort both arrays for efficient search 115 | sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0); 116 | 117 | this._finished = true; 118 | return this; 119 | } 120 | 121 | /** 122 | * Search the index for items within a given bounding box. 123 | * @param {number} minX 124 | * @param {number} minY 125 | * @param {number} maxX 126 | * @param {number} maxY 127 | * @returns {number[]} An array of indices correponding to the found items. 128 | */ 129 | range(minX, minY, maxX, maxY) { 130 | if (!this._finished) throw new Error('Data not yet indexed - call index.finish().'); 131 | 132 | const {ids, coords, nodeSize} = this; 133 | const stack = [0, ids.length - 1, 0]; 134 | const result = []; 135 | 136 | // recursively search for items in range in the kd-sorted arrays 137 | while (stack.length) { 138 | const axis = stack.pop() || 0; 139 | const right = stack.pop() || 0; 140 | const left = stack.pop() || 0; 141 | 142 | // if we reached "tree node", search linearly 143 | if (right - left <= nodeSize) { 144 | for (let i = left; i <= right; i++) { 145 | const x = coords[2 * i]; 146 | const y = coords[2 * i + 1]; 147 | if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]); 148 | } 149 | continue; 150 | } 151 | 152 | // otherwise find the middle index 153 | const m = (left + right) >> 1; 154 | 155 | // include the middle item if it's in range 156 | const x = coords[2 * m]; 157 | const y = coords[2 * m + 1]; 158 | if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]); 159 | 160 | // queue search in halves that intersect the query 161 | if (axis === 0 ? minX <= x : minY <= y) { 162 | stack.push(left); 163 | stack.push(m - 1); 164 | stack.push(1 - axis); 165 | } 166 | if (axis === 0 ? maxX >= x : maxY >= y) { 167 | stack.push(m + 1); 168 | stack.push(right); 169 | stack.push(1 - axis); 170 | } 171 | } 172 | 173 | return result; 174 | } 175 | 176 | /** 177 | * Search the index for items within a given radius. 178 | * @param {number} qx 179 | * @param {number} qy 180 | * @param {number} r Query radius. 181 | * @returns {number[]} An array of indices correponding to the found items. 182 | */ 183 | within(qx, qy, r) { 184 | if (!this._finished) throw new Error('Data not yet indexed - call index.finish().'); 185 | 186 | const {ids, coords, nodeSize} = this; 187 | const stack = [0, ids.length - 1, 0]; 188 | const result = []; 189 | const r2 = r * r; 190 | 191 | // recursively search for items within radius in the kd-sorted arrays 192 | while (stack.length) { 193 | const axis = stack.pop() || 0; 194 | const right = stack.pop() || 0; 195 | const left = stack.pop() || 0; 196 | 197 | // if we reached "tree node", search linearly 198 | if (right - left <= nodeSize) { 199 | for (let i = left; i <= right; i++) { 200 | if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) result.push(ids[i]); 201 | } 202 | continue; 203 | } 204 | 205 | // otherwise find the middle index 206 | const m = (left + right) >> 1; 207 | 208 | // include the middle item if it's in range 209 | const x = coords[2 * m]; 210 | const y = coords[2 * m + 1]; 211 | if (sqDist(x, y, qx, qy) <= r2) result.push(ids[m]); 212 | 213 | // queue search in halves that intersect the query 214 | if (axis === 0 ? qx - r <= x : qy - r <= y) { 215 | stack.push(left); 216 | stack.push(m - 1); 217 | stack.push(1 - axis); 218 | } 219 | if (axis === 0 ? qx + r >= x : qy + r >= y) { 220 | stack.push(m + 1); 221 | stack.push(right); 222 | stack.push(1 - axis); 223 | } 224 | } 225 | 226 | return result; 227 | } 228 | } 229 | 230 | /** 231 | * @param {Uint16Array | Uint32Array} ids 232 | * @param {TypedArray} coords 233 | * @param {number} nodeSize 234 | * @param {number} left 235 | * @param {number} right 236 | * @param {number} axis 237 | */ 238 | function sort(ids, coords, nodeSize, left, right, axis) { 239 | if (right - left <= nodeSize) return; 240 | 241 | const m = (left + right) >> 1; // middle index 242 | 243 | // sort ids and coords around the middle index so that the halves lie 244 | // either left/right or top/bottom correspondingly (taking turns) 245 | select(ids, coords, m, left, right, axis); 246 | 247 | // recursively kd-sort first half and second half on the opposite axis 248 | sort(ids, coords, nodeSize, left, m - 1, 1 - axis); 249 | sort(ids, coords, nodeSize, m + 1, right, 1 - axis); 250 | } 251 | 252 | /** 253 | * Custom Floyd-Rivest selection algorithm: sort ids and coords so that 254 | * [left..k-1] items are smaller than k-th item (on either x or y axis) 255 | * @param {Uint16Array | Uint32Array} ids 256 | * @param {TypedArray} coords 257 | * @param {number} k 258 | * @param {number} left 259 | * @param {number} right 260 | * @param {number} axis 261 | */ 262 | function select(ids, coords, k, left, right, axis) { 263 | 264 | while (right > left) { 265 | if (right - left > 600) { 266 | const n = right - left + 1; 267 | const m = k - left + 1; 268 | const z = Math.log(n); 269 | const s = 0.5 * Math.exp(2 * z / 3); 270 | const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); 271 | const newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); 272 | const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); 273 | select(ids, coords, k, newLeft, newRight, axis); 274 | } 275 | 276 | const t = coords[2 * k + axis]; 277 | let i = left; 278 | let j = right; 279 | 280 | swapItem(ids, coords, left, k); 281 | if (coords[2 * right + axis] > t) swapItem(ids, coords, left, right); 282 | 283 | while (i < j) { 284 | swapItem(ids, coords, i, j); 285 | i++; 286 | j--; 287 | while (coords[2 * i + axis] < t) i++; 288 | while (coords[2 * j + axis] > t) j--; 289 | } 290 | 291 | if (coords[2 * left + axis] === t) swapItem(ids, coords, left, j); 292 | else { 293 | j++; 294 | swapItem(ids, coords, j, right); 295 | } 296 | 297 | if (j <= k) left = j + 1; 298 | if (k <= j) right = j - 1; 299 | } 300 | } 301 | 302 | /** 303 | * @param {Uint16Array | Uint32Array} ids 304 | * @param {TypedArray} coords 305 | * @param {number} i 306 | * @param {number} j 307 | */ 308 | function swapItem(ids, coords, i, j) { 309 | swap(ids, i, j); 310 | swap(coords, 2 * i, 2 * j); 311 | swap(coords, 2 * i + 1, 2 * j + 1); 312 | } 313 | 314 | /** 315 | * @param {TypedArray} arr 316 | * @param {number} i 317 | * @param {number} j 318 | */ 319 | function swap(arr, i, j) { 320 | const tmp = arr[i]; 321 | arr[i] = arr[j]; 322 | arr[j] = tmp; 323 | } 324 | 325 | /** 326 | * @param {number} ax 327 | * @param {number} ay 328 | * @param {number} bx 329 | * @param {number} by 330 | */ 331 | function sqDist(ax, ay, bx, by) { 332 | const dx = ax - bx; 333 | const dy = ay - by; 334 | return dx * dx + dy * dy; 335 | } 336 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kdbush", 3 | "version": "4.0.2", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "kdbush", 9 | "version": "4.0.2", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@rollup/plugin-terser": "^0.4.4", 13 | "eslint": "^9.33.0", 14 | "eslint-config-mourner": "^4.1.0", 15 | "rollup": "^4.46.2", 16 | "typescript": "^5.9.2" 17 | } 18 | }, 19 | "node_modules/@eslint-community/eslint-utils": { 20 | "version": "4.7.0", 21 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", 22 | "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", 23 | "dev": true, 24 | "license": "MIT", 25 | "dependencies": { 26 | "eslint-visitor-keys": "^3.4.3" 27 | }, 28 | "engines": { 29 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 30 | }, 31 | "funding": { 32 | "url": "https://opencollective.com/eslint" 33 | }, 34 | "peerDependencies": { 35 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 36 | } 37 | }, 38 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 39 | "version": "3.4.3", 40 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 41 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 42 | "dev": true, 43 | "license": "Apache-2.0", 44 | "engines": { 45 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 46 | }, 47 | "funding": { 48 | "url": "https://opencollective.com/eslint" 49 | } 50 | }, 51 | "node_modules/@eslint-community/regexpp": { 52 | "version": "4.12.1", 53 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 54 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 55 | "dev": true, 56 | "license": "MIT", 57 | "engines": { 58 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 59 | } 60 | }, 61 | "node_modules/@eslint/config-array": { 62 | "version": "0.21.0", 63 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", 64 | "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", 65 | "dev": true, 66 | "license": "Apache-2.0", 67 | "dependencies": { 68 | "@eslint/object-schema": "^2.1.6", 69 | "debug": "^4.3.1", 70 | "minimatch": "^3.1.2" 71 | }, 72 | "engines": { 73 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 74 | } 75 | }, 76 | "node_modules/@eslint/config-helpers": { 77 | "version": "0.3.1", 78 | "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", 79 | "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", 80 | "dev": true, 81 | "license": "Apache-2.0", 82 | "engines": { 83 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 84 | } 85 | }, 86 | "node_modules/@eslint/core": { 87 | "version": "0.15.2", 88 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", 89 | "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", 90 | "dev": true, 91 | "license": "Apache-2.0", 92 | "dependencies": { 93 | "@types/json-schema": "^7.0.15" 94 | }, 95 | "engines": { 96 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 97 | } 98 | }, 99 | "node_modules/@eslint/eslintrc": { 100 | "version": "3.3.1", 101 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", 102 | "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", 103 | "dev": true, 104 | "license": "MIT", 105 | "dependencies": { 106 | "ajv": "^6.12.4", 107 | "debug": "^4.3.2", 108 | "espree": "^10.0.1", 109 | "globals": "^14.0.0", 110 | "ignore": "^5.2.0", 111 | "import-fresh": "^3.2.1", 112 | "js-yaml": "^4.1.0", 113 | "minimatch": "^3.1.2", 114 | "strip-json-comments": "^3.1.1" 115 | }, 116 | "engines": { 117 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 118 | }, 119 | "funding": { 120 | "url": "https://opencollective.com/eslint" 121 | } 122 | }, 123 | "node_modules/@eslint/js": { 124 | "version": "9.33.0", 125 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz", 126 | "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==", 127 | "dev": true, 128 | "license": "MIT", 129 | "engines": { 130 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 131 | }, 132 | "funding": { 133 | "url": "https://eslint.org/donate" 134 | } 135 | }, 136 | "node_modules/@eslint/object-schema": { 137 | "version": "2.1.6", 138 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 139 | "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 140 | "dev": true, 141 | "license": "Apache-2.0", 142 | "engines": { 143 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 144 | } 145 | }, 146 | "node_modules/@eslint/plugin-kit": { 147 | "version": "0.3.5", 148 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", 149 | "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", 150 | "dev": true, 151 | "license": "Apache-2.0", 152 | "dependencies": { 153 | "@eslint/core": "^0.15.2", 154 | "levn": "^0.4.1" 155 | }, 156 | "engines": { 157 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 158 | } 159 | }, 160 | "node_modules/@humanfs/core": { 161 | "version": "0.19.1", 162 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 163 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 164 | "dev": true, 165 | "license": "Apache-2.0", 166 | "engines": { 167 | "node": ">=18.18.0" 168 | } 169 | }, 170 | "node_modules/@humanfs/node": { 171 | "version": "0.16.6", 172 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 173 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 174 | "dev": true, 175 | "license": "Apache-2.0", 176 | "dependencies": { 177 | "@humanfs/core": "^0.19.1", 178 | "@humanwhocodes/retry": "^0.3.0" 179 | }, 180 | "engines": { 181 | "node": ">=18.18.0" 182 | } 183 | }, 184 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 185 | "version": "0.3.1", 186 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 187 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 188 | "dev": true, 189 | "license": "Apache-2.0", 190 | "engines": { 191 | "node": ">=18.18" 192 | }, 193 | "funding": { 194 | "type": "github", 195 | "url": "https://github.com/sponsors/nzakas" 196 | } 197 | }, 198 | "node_modules/@humanwhocodes/module-importer": { 199 | "version": "1.0.1", 200 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 201 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 202 | "dev": true, 203 | "license": "Apache-2.0", 204 | "engines": { 205 | "node": ">=12.22" 206 | }, 207 | "funding": { 208 | "type": "github", 209 | "url": "https://github.com/sponsors/nzakas" 210 | } 211 | }, 212 | "node_modules/@humanwhocodes/retry": { 213 | "version": "0.4.3", 214 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", 215 | "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", 216 | "dev": true, 217 | "license": "Apache-2.0", 218 | "engines": { 219 | "node": ">=18.18" 220 | }, 221 | "funding": { 222 | "type": "github", 223 | "url": "https://github.com/sponsors/nzakas" 224 | } 225 | }, 226 | "node_modules/@jridgewell/gen-mapping": { 227 | "version": "0.3.12", 228 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", 229 | "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", 230 | "dev": true, 231 | "license": "MIT", 232 | "dependencies": { 233 | "@jridgewell/sourcemap-codec": "^1.5.0", 234 | "@jridgewell/trace-mapping": "^0.3.24" 235 | } 236 | }, 237 | "node_modules/@jridgewell/resolve-uri": { 238 | "version": "3.1.2", 239 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 240 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 241 | "dev": true, 242 | "license": "MIT", 243 | "engines": { 244 | "node": ">=6.0.0" 245 | } 246 | }, 247 | "node_modules/@jridgewell/source-map": { 248 | "version": "0.3.10", 249 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", 250 | "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", 251 | "dev": true, 252 | "license": "MIT", 253 | "dependencies": { 254 | "@jridgewell/gen-mapping": "^0.3.5", 255 | "@jridgewell/trace-mapping": "^0.3.25" 256 | } 257 | }, 258 | "node_modules/@jridgewell/sourcemap-codec": { 259 | "version": "1.5.4", 260 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", 261 | "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", 262 | "dev": true, 263 | "license": "MIT" 264 | }, 265 | "node_modules/@jridgewell/trace-mapping": { 266 | "version": "0.3.29", 267 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", 268 | "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", 269 | "dev": true, 270 | "license": "MIT", 271 | "dependencies": { 272 | "@jridgewell/resolve-uri": "^3.1.0", 273 | "@jridgewell/sourcemap-codec": "^1.4.14" 274 | } 275 | }, 276 | "node_modules/@rollup/plugin-terser": { 277 | "version": "0.4.4", 278 | "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", 279 | "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", 280 | "dev": true, 281 | "license": "MIT", 282 | "dependencies": { 283 | "serialize-javascript": "^6.0.1", 284 | "smob": "^1.0.0", 285 | "terser": "^5.17.4" 286 | }, 287 | "engines": { 288 | "node": ">=14.0.0" 289 | }, 290 | "peerDependencies": { 291 | "rollup": "^2.0.0||^3.0.0||^4.0.0" 292 | }, 293 | "peerDependenciesMeta": { 294 | "rollup": { 295 | "optional": true 296 | } 297 | } 298 | }, 299 | "node_modules/@rollup/rollup-android-arm-eabi": { 300 | "version": "4.46.2", 301 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", 302 | "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", 303 | "cpu": [ 304 | "arm" 305 | ], 306 | "dev": true, 307 | "license": "MIT", 308 | "optional": true, 309 | "os": [ 310 | "android" 311 | ] 312 | }, 313 | "node_modules/@rollup/rollup-android-arm64": { 314 | "version": "4.46.2", 315 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", 316 | "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", 317 | "cpu": [ 318 | "arm64" 319 | ], 320 | "dev": true, 321 | "license": "MIT", 322 | "optional": true, 323 | "os": [ 324 | "android" 325 | ] 326 | }, 327 | "node_modules/@rollup/rollup-darwin-arm64": { 328 | "version": "4.46.2", 329 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", 330 | "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", 331 | "cpu": [ 332 | "arm64" 333 | ], 334 | "dev": true, 335 | "license": "MIT", 336 | "optional": true, 337 | "os": [ 338 | "darwin" 339 | ] 340 | }, 341 | "node_modules/@rollup/rollup-darwin-x64": { 342 | "version": "4.46.2", 343 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", 344 | "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", 345 | "cpu": [ 346 | "x64" 347 | ], 348 | "dev": true, 349 | "license": "MIT", 350 | "optional": true, 351 | "os": [ 352 | "darwin" 353 | ] 354 | }, 355 | "node_modules/@rollup/rollup-freebsd-arm64": { 356 | "version": "4.46.2", 357 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", 358 | "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", 359 | "cpu": [ 360 | "arm64" 361 | ], 362 | "dev": true, 363 | "license": "MIT", 364 | "optional": true, 365 | "os": [ 366 | "freebsd" 367 | ] 368 | }, 369 | "node_modules/@rollup/rollup-freebsd-x64": { 370 | "version": "4.46.2", 371 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", 372 | "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", 373 | "cpu": [ 374 | "x64" 375 | ], 376 | "dev": true, 377 | "license": "MIT", 378 | "optional": true, 379 | "os": [ 380 | "freebsd" 381 | ] 382 | }, 383 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 384 | "version": "4.46.2", 385 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", 386 | "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", 387 | "cpu": [ 388 | "arm" 389 | ], 390 | "dev": true, 391 | "license": "MIT", 392 | "optional": true, 393 | "os": [ 394 | "linux" 395 | ] 396 | }, 397 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 398 | "version": "4.46.2", 399 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", 400 | "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", 401 | "cpu": [ 402 | "arm" 403 | ], 404 | "dev": true, 405 | "license": "MIT", 406 | "optional": true, 407 | "os": [ 408 | "linux" 409 | ] 410 | }, 411 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 412 | "version": "4.46.2", 413 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", 414 | "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", 415 | "cpu": [ 416 | "arm64" 417 | ], 418 | "dev": true, 419 | "license": "MIT", 420 | "optional": true, 421 | "os": [ 422 | "linux" 423 | ] 424 | }, 425 | "node_modules/@rollup/rollup-linux-arm64-musl": { 426 | "version": "4.46.2", 427 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", 428 | "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", 429 | "cpu": [ 430 | "arm64" 431 | ], 432 | "dev": true, 433 | "license": "MIT", 434 | "optional": true, 435 | "os": [ 436 | "linux" 437 | ] 438 | }, 439 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 440 | "version": "4.46.2", 441 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", 442 | "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", 443 | "cpu": [ 444 | "loong64" 445 | ], 446 | "dev": true, 447 | "license": "MIT", 448 | "optional": true, 449 | "os": [ 450 | "linux" 451 | ] 452 | }, 453 | "node_modules/@rollup/rollup-linux-ppc64-gnu": { 454 | "version": "4.46.2", 455 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", 456 | "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", 457 | "cpu": [ 458 | "ppc64" 459 | ], 460 | "dev": true, 461 | "license": "MIT", 462 | "optional": true, 463 | "os": [ 464 | "linux" 465 | ] 466 | }, 467 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 468 | "version": "4.46.2", 469 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", 470 | "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", 471 | "cpu": [ 472 | "riscv64" 473 | ], 474 | "dev": true, 475 | "license": "MIT", 476 | "optional": true, 477 | "os": [ 478 | "linux" 479 | ] 480 | }, 481 | "node_modules/@rollup/rollup-linux-riscv64-musl": { 482 | "version": "4.46.2", 483 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", 484 | "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", 485 | "cpu": [ 486 | "riscv64" 487 | ], 488 | "dev": true, 489 | "license": "MIT", 490 | "optional": true, 491 | "os": [ 492 | "linux" 493 | ] 494 | }, 495 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 496 | "version": "4.46.2", 497 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", 498 | "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", 499 | "cpu": [ 500 | "s390x" 501 | ], 502 | "dev": true, 503 | "license": "MIT", 504 | "optional": true, 505 | "os": [ 506 | "linux" 507 | ] 508 | }, 509 | "node_modules/@rollup/rollup-linux-x64-gnu": { 510 | "version": "4.46.2", 511 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", 512 | "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", 513 | "cpu": [ 514 | "x64" 515 | ], 516 | "dev": true, 517 | "license": "MIT", 518 | "optional": true, 519 | "os": [ 520 | "linux" 521 | ] 522 | }, 523 | "node_modules/@rollup/rollup-linux-x64-musl": { 524 | "version": "4.46.2", 525 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", 526 | "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", 527 | "cpu": [ 528 | "x64" 529 | ], 530 | "dev": true, 531 | "license": "MIT", 532 | "optional": true, 533 | "os": [ 534 | "linux" 535 | ] 536 | }, 537 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 538 | "version": "4.46.2", 539 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", 540 | "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", 541 | "cpu": [ 542 | "arm64" 543 | ], 544 | "dev": true, 545 | "license": "MIT", 546 | "optional": true, 547 | "os": [ 548 | "win32" 549 | ] 550 | }, 551 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 552 | "version": "4.46.2", 553 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", 554 | "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", 555 | "cpu": [ 556 | "ia32" 557 | ], 558 | "dev": true, 559 | "license": "MIT", 560 | "optional": true, 561 | "os": [ 562 | "win32" 563 | ] 564 | }, 565 | "node_modules/@rollup/rollup-win32-x64-msvc": { 566 | "version": "4.46.2", 567 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", 568 | "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", 569 | "cpu": [ 570 | "x64" 571 | ], 572 | "dev": true, 573 | "license": "MIT", 574 | "optional": true, 575 | "os": [ 576 | "win32" 577 | ] 578 | }, 579 | "node_modules/@stylistic/eslint-plugin": { 580 | "version": "5.2.3", 581 | "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.2.3.tgz", 582 | "integrity": "sha512-oY7GVkJGVMI5benlBDCaRrSC1qPasafyv5dOBLLv5MTilMGnErKhO6ziEfodDDIZbo5QxPUNW360VudJOFODMw==", 583 | "dev": true, 584 | "license": "MIT", 585 | "dependencies": { 586 | "@eslint-community/eslint-utils": "^4.7.0", 587 | "@typescript-eslint/types": "^8.38.0", 588 | "eslint-visitor-keys": "^4.2.1", 589 | "espree": "^10.4.0", 590 | "estraverse": "^5.3.0", 591 | "picomatch": "^4.0.3" 592 | }, 593 | "engines": { 594 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 595 | }, 596 | "peerDependencies": { 597 | "eslint": ">=9.0.0" 598 | } 599 | }, 600 | "node_modules/@types/estree": { 601 | "version": "1.0.8", 602 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", 603 | "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", 604 | "dev": true, 605 | "license": "MIT" 606 | }, 607 | "node_modules/@types/json-schema": { 608 | "version": "7.0.15", 609 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 610 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 611 | "dev": true, 612 | "license": "MIT" 613 | }, 614 | "node_modules/@typescript-eslint/types": { 615 | "version": "8.39.0", 616 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", 617 | "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", 618 | "dev": true, 619 | "license": "MIT", 620 | "engines": { 621 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 622 | }, 623 | "funding": { 624 | "type": "opencollective", 625 | "url": "https://opencollective.com/typescript-eslint" 626 | } 627 | }, 628 | "node_modules/acorn": { 629 | "version": "8.15.0", 630 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", 631 | "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", 632 | "dev": true, 633 | "license": "MIT", 634 | "bin": { 635 | "acorn": "bin/acorn" 636 | }, 637 | "engines": { 638 | "node": ">=0.4.0" 639 | } 640 | }, 641 | "node_modules/acorn-jsx": { 642 | "version": "5.3.2", 643 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 644 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 645 | "dev": true, 646 | "license": "MIT", 647 | "peerDependencies": { 648 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 649 | } 650 | }, 651 | "node_modules/ajv": { 652 | "version": "6.12.6", 653 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 654 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 655 | "dev": true, 656 | "license": "MIT", 657 | "dependencies": { 658 | "fast-deep-equal": "^3.1.1", 659 | "fast-json-stable-stringify": "^2.0.0", 660 | "json-schema-traverse": "^0.4.1", 661 | "uri-js": "^4.2.2" 662 | }, 663 | "funding": { 664 | "type": "github", 665 | "url": "https://github.com/sponsors/epoberezkin" 666 | } 667 | }, 668 | "node_modules/ansi-styles": { 669 | "version": "4.3.0", 670 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 671 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 672 | "dev": true, 673 | "license": "MIT", 674 | "dependencies": { 675 | "color-convert": "^2.0.1" 676 | }, 677 | "engines": { 678 | "node": ">=8" 679 | }, 680 | "funding": { 681 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 682 | } 683 | }, 684 | "node_modules/argparse": { 685 | "version": "2.0.1", 686 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 687 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 688 | "dev": true, 689 | "license": "Python-2.0" 690 | }, 691 | "node_modules/balanced-match": { 692 | "version": "1.0.2", 693 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 694 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 695 | "dev": true, 696 | "license": "MIT" 697 | }, 698 | "node_modules/brace-expansion": { 699 | "version": "1.1.12", 700 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", 701 | "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", 702 | "dev": true, 703 | "license": "MIT", 704 | "dependencies": { 705 | "balanced-match": "^1.0.0", 706 | "concat-map": "0.0.1" 707 | } 708 | }, 709 | "node_modules/buffer-from": { 710 | "version": "1.1.2", 711 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 712 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 713 | "dev": true, 714 | "license": "MIT" 715 | }, 716 | "node_modules/callsites": { 717 | "version": "3.1.0", 718 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 719 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 720 | "dev": true, 721 | "license": "MIT", 722 | "engines": { 723 | "node": ">=6" 724 | } 725 | }, 726 | "node_modules/chalk": { 727 | "version": "4.1.2", 728 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 729 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 730 | "dev": true, 731 | "license": "MIT", 732 | "dependencies": { 733 | "ansi-styles": "^4.1.0", 734 | "supports-color": "^7.1.0" 735 | }, 736 | "engines": { 737 | "node": ">=10" 738 | }, 739 | "funding": { 740 | "url": "https://github.com/chalk/chalk?sponsor=1" 741 | } 742 | }, 743 | "node_modules/color-convert": { 744 | "version": "2.0.1", 745 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 746 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 747 | "dev": true, 748 | "license": "MIT", 749 | "dependencies": { 750 | "color-name": "~1.1.4" 751 | }, 752 | "engines": { 753 | "node": ">=7.0.0" 754 | } 755 | }, 756 | "node_modules/color-name": { 757 | "version": "1.1.4", 758 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 759 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 760 | "dev": true, 761 | "license": "MIT" 762 | }, 763 | "node_modules/commander": { 764 | "version": "2.20.3", 765 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 766 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 767 | "dev": true, 768 | "license": "MIT" 769 | }, 770 | "node_modules/concat-map": { 771 | "version": "0.0.1", 772 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 773 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 774 | "dev": true, 775 | "license": "MIT" 776 | }, 777 | "node_modules/cross-spawn": { 778 | "version": "7.0.6", 779 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 780 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 781 | "dev": true, 782 | "license": "MIT", 783 | "dependencies": { 784 | "path-key": "^3.1.0", 785 | "shebang-command": "^2.0.0", 786 | "which": "^2.0.1" 787 | }, 788 | "engines": { 789 | "node": ">= 8" 790 | } 791 | }, 792 | "node_modules/debug": { 793 | "version": "4.4.1", 794 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", 795 | "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", 796 | "dev": true, 797 | "license": "MIT", 798 | "dependencies": { 799 | "ms": "^2.1.3" 800 | }, 801 | "engines": { 802 | "node": ">=6.0" 803 | }, 804 | "peerDependenciesMeta": { 805 | "supports-color": { 806 | "optional": true 807 | } 808 | } 809 | }, 810 | "node_modules/deep-is": { 811 | "version": "0.1.4", 812 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 813 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 814 | "dev": true, 815 | "license": "MIT" 816 | }, 817 | "node_modules/escape-string-regexp": { 818 | "version": "4.0.0", 819 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 820 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 821 | "dev": true, 822 | "license": "MIT", 823 | "engines": { 824 | "node": ">=10" 825 | }, 826 | "funding": { 827 | "url": "https://github.com/sponsors/sindresorhus" 828 | } 829 | }, 830 | "node_modules/eslint": { 831 | "version": "9.33.0", 832 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz", 833 | "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", 834 | "dev": true, 835 | "license": "MIT", 836 | "dependencies": { 837 | "@eslint-community/eslint-utils": "^4.2.0", 838 | "@eslint-community/regexpp": "^4.12.1", 839 | "@eslint/config-array": "^0.21.0", 840 | "@eslint/config-helpers": "^0.3.1", 841 | "@eslint/core": "^0.15.2", 842 | "@eslint/eslintrc": "^3.3.1", 843 | "@eslint/js": "9.33.0", 844 | "@eslint/plugin-kit": "^0.3.5", 845 | "@humanfs/node": "^0.16.6", 846 | "@humanwhocodes/module-importer": "^1.0.1", 847 | "@humanwhocodes/retry": "^0.4.2", 848 | "@types/estree": "^1.0.6", 849 | "@types/json-schema": "^7.0.15", 850 | "ajv": "^6.12.4", 851 | "chalk": "^4.0.0", 852 | "cross-spawn": "^7.0.6", 853 | "debug": "^4.3.2", 854 | "escape-string-regexp": "^4.0.0", 855 | "eslint-scope": "^8.4.0", 856 | "eslint-visitor-keys": "^4.2.1", 857 | "espree": "^10.4.0", 858 | "esquery": "^1.5.0", 859 | "esutils": "^2.0.2", 860 | "fast-deep-equal": "^3.1.3", 861 | "file-entry-cache": "^8.0.0", 862 | "find-up": "^5.0.0", 863 | "glob-parent": "^6.0.2", 864 | "ignore": "^5.2.0", 865 | "imurmurhash": "^0.1.4", 866 | "is-glob": "^4.0.0", 867 | "json-stable-stringify-without-jsonify": "^1.0.1", 868 | "lodash.merge": "^4.6.2", 869 | "minimatch": "^3.1.2", 870 | "natural-compare": "^1.4.0", 871 | "optionator": "^0.9.3" 872 | }, 873 | "bin": { 874 | "eslint": "bin/eslint.js" 875 | }, 876 | "engines": { 877 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 878 | }, 879 | "funding": { 880 | "url": "https://eslint.org/donate" 881 | }, 882 | "peerDependencies": { 883 | "jiti": "*" 884 | }, 885 | "peerDependenciesMeta": { 886 | "jiti": { 887 | "optional": true 888 | } 889 | } 890 | }, 891 | "node_modules/eslint-config-mourner": { 892 | "version": "4.1.0", 893 | "resolved": "https://registry.npmjs.org/eslint-config-mourner/-/eslint-config-mourner-4.1.0.tgz", 894 | "integrity": "sha512-XEPuEuauqbnLPi/QZGjZr57w2+quw1fEXa2p6jz3tR8ggDk/ciMjiQo7/PR43t47osdS/RaduN/T1MGncwmOKQ==", 895 | "dev": true, 896 | "license": "ISC", 897 | "dependencies": { 898 | "@eslint/js": "^9.31.0", 899 | "@stylistic/eslint-plugin": "^5.1.0", 900 | "globals": "^16.3.0" 901 | } 902 | }, 903 | "node_modules/eslint-config-mourner/node_modules/globals": { 904 | "version": "16.3.0", 905 | "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", 906 | "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", 907 | "dev": true, 908 | "license": "MIT", 909 | "engines": { 910 | "node": ">=18" 911 | }, 912 | "funding": { 913 | "url": "https://github.com/sponsors/sindresorhus" 914 | } 915 | }, 916 | "node_modules/eslint-scope": { 917 | "version": "8.4.0", 918 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", 919 | "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", 920 | "dev": true, 921 | "license": "BSD-2-Clause", 922 | "dependencies": { 923 | "esrecurse": "^4.3.0", 924 | "estraverse": "^5.2.0" 925 | }, 926 | "engines": { 927 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 928 | }, 929 | "funding": { 930 | "url": "https://opencollective.com/eslint" 931 | } 932 | }, 933 | "node_modules/eslint-visitor-keys": { 934 | "version": "4.2.1", 935 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", 936 | "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", 937 | "dev": true, 938 | "license": "Apache-2.0", 939 | "engines": { 940 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 941 | }, 942 | "funding": { 943 | "url": "https://opencollective.com/eslint" 944 | } 945 | }, 946 | "node_modules/espree": { 947 | "version": "10.4.0", 948 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", 949 | "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", 950 | "dev": true, 951 | "license": "BSD-2-Clause", 952 | "dependencies": { 953 | "acorn": "^8.15.0", 954 | "acorn-jsx": "^5.3.2", 955 | "eslint-visitor-keys": "^4.2.1" 956 | }, 957 | "engines": { 958 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 959 | }, 960 | "funding": { 961 | "url": "https://opencollective.com/eslint" 962 | } 963 | }, 964 | "node_modules/esquery": { 965 | "version": "1.6.0", 966 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 967 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 968 | "dev": true, 969 | "license": "BSD-3-Clause", 970 | "dependencies": { 971 | "estraverse": "^5.1.0" 972 | }, 973 | "engines": { 974 | "node": ">=0.10" 975 | } 976 | }, 977 | "node_modules/esrecurse": { 978 | "version": "4.3.0", 979 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 980 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 981 | "dev": true, 982 | "license": "BSD-2-Clause", 983 | "dependencies": { 984 | "estraverse": "^5.2.0" 985 | }, 986 | "engines": { 987 | "node": ">=4.0" 988 | } 989 | }, 990 | "node_modules/estraverse": { 991 | "version": "5.3.0", 992 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 993 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 994 | "dev": true, 995 | "license": "BSD-2-Clause", 996 | "engines": { 997 | "node": ">=4.0" 998 | } 999 | }, 1000 | "node_modules/esutils": { 1001 | "version": "2.0.3", 1002 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1003 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1004 | "dev": true, 1005 | "license": "BSD-2-Clause", 1006 | "engines": { 1007 | "node": ">=0.10.0" 1008 | } 1009 | }, 1010 | "node_modules/fast-deep-equal": { 1011 | "version": "3.1.3", 1012 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1013 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1014 | "dev": true, 1015 | "license": "MIT" 1016 | }, 1017 | "node_modules/fast-json-stable-stringify": { 1018 | "version": "2.1.0", 1019 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1020 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1021 | "dev": true, 1022 | "license": "MIT" 1023 | }, 1024 | "node_modules/fast-levenshtein": { 1025 | "version": "2.0.6", 1026 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1027 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1028 | "dev": true, 1029 | "license": "MIT" 1030 | }, 1031 | "node_modules/file-entry-cache": { 1032 | "version": "8.0.0", 1033 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 1034 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 1035 | "dev": true, 1036 | "license": "MIT", 1037 | "dependencies": { 1038 | "flat-cache": "^4.0.0" 1039 | }, 1040 | "engines": { 1041 | "node": ">=16.0.0" 1042 | } 1043 | }, 1044 | "node_modules/find-up": { 1045 | "version": "5.0.0", 1046 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1047 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1048 | "dev": true, 1049 | "license": "MIT", 1050 | "dependencies": { 1051 | "locate-path": "^6.0.0", 1052 | "path-exists": "^4.0.0" 1053 | }, 1054 | "engines": { 1055 | "node": ">=10" 1056 | }, 1057 | "funding": { 1058 | "url": "https://github.com/sponsors/sindresorhus" 1059 | } 1060 | }, 1061 | "node_modules/flat-cache": { 1062 | "version": "4.0.1", 1063 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 1064 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 1065 | "dev": true, 1066 | "license": "MIT", 1067 | "dependencies": { 1068 | "flatted": "^3.2.9", 1069 | "keyv": "^4.5.4" 1070 | }, 1071 | "engines": { 1072 | "node": ">=16" 1073 | } 1074 | }, 1075 | "node_modules/flatted": { 1076 | "version": "3.3.3", 1077 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 1078 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 1079 | "dev": true, 1080 | "license": "ISC" 1081 | }, 1082 | "node_modules/fsevents": { 1083 | "version": "2.3.3", 1084 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1085 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1086 | "dev": true, 1087 | "hasInstallScript": true, 1088 | "license": "MIT", 1089 | "optional": true, 1090 | "os": [ 1091 | "darwin" 1092 | ], 1093 | "engines": { 1094 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1095 | } 1096 | }, 1097 | "node_modules/glob-parent": { 1098 | "version": "6.0.2", 1099 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1100 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1101 | "dev": true, 1102 | "license": "ISC", 1103 | "dependencies": { 1104 | "is-glob": "^4.0.3" 1105 | }, 1106 | "engines": { 1107 | "node": ">=10.13.0" 1108 | } 1109 | }, 1110 | "node_modules/globals": { 1111 | "version": "14.0.0", 1112 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 1113 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 1114 | "dev": true, 1115 | "license": "MIT", 1116 | "engines": { 1117 | "node": ">=18" 1118 | }, 1119 | "funding": { 1120 | "url": "https://github.com/sponsors/sindresorhus" 1121 | } 1122 | }, 1123 | "node_modules/has-flag": { 1124 | "version": "4.0.0", 1125 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1126 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1127 | "dev": true, 1128 | "license": "MIT", 1129 | "engines": { 1130 | "node": ">=8" 1131 | } 1132 | }, 1133 | "node_modules/ignore": { 1134 | "version": "5.3.2", 1135 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 1136 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 1137 | "dev": true, 1138 | "license": "MIT", 1139 | "engines": { 1140 | "node": ">= 4" 1141 | } 1142 | }, 1143 | "node_modules/import-fresh": { 1144 | "version": "3.3.1", 1145 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 1146 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 1147 | "dev": true, 1148 | "license": "MIT", 1149 | "dependencies": { 1150 | "parent-module": "^1.0.0", 1151 | "resolve-from": "^4.0.0" 1152 | }, 1153 | "engines": { 1154 | "node": ">=6" 1155 | }, 1156 | "funding": { 1157 | "url": "https://github.com/sponsors/sindresorhus" 1158 | } 1159 | }, 1160 | "node_modules/imurmurhash": { 1161 | "version": "0.1.4", 1162 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1163 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1164 | "dev": true, 1165 | "license": "MIT", 1166 | "engines": { 1167 | "node": ">=0.8.19" 1168 | } 1169 | }, 1170 | "node_modules/is-extglob": { 1171 | "version": "2.1.1", 1172 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1173 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1174 | "dev": true, 1175 | "license": "MIT", 1176 | "engines": { 1177 | "node": ">=0.10.0" 1178 | } 1179 | }, 1180 | "node_modules/is-glob": { 1181 | "version": "4.0.3", 1182 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1183 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1184 | "dev": true, 1185 | "license": "MIT", 1186 | "dependencies": { 1187 | "is-extglob": "^2.1.1" 1188 | }, 1189 | "engines": { 1190 | "node": ">=0.10.0" 1191 | } 1192 | }, 1193 | "node_modules/isexe": { 1194 | "version": "2.0.0", 1195 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1196 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1197 | "dev": true, 1198 | "license": "ISC" 1199 | }, 1200 | "node_modules/js-yaml": { 1201 | "version": "4.1.0", 1202 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1203 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1204 | "dev": true, 1205 | "license": "MIT", 1206 | "dependencies": { 1207 | "argparse": "^2.0.1" 1208 | }, 1209 | "bin": { 1210 | "js-yaml": "bin/js-yaml.js" 1211 | } 1212 | }, 1213 | "node_modules/json-buffer": { 1214 | "version": "3.0.1", 1215 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 1216 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 1217 | "dev": true, 1218 | "license": "MIT" 1219 | }, 1220 | "node_modules/json-schema-traverse": { 1221 | "version": "0.4.1", 1222 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1223 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1224 | "dev": true, 1225 | "license": "MIT" 1226 | }, 1227 | "node_modules/json-stable-stringify-without-jsonify": { 1228 | "version": "1.0.1", 1229 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1230 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 1231 | "dev": true, 1232 | "license": "MIT" 1233 | }, 1234 | "node_modules/keyv": { 1235 | "version": "4.5.4", 1236 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 1237 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 1238 | "dev": true, 1239 | "license": "MIT", 1240 | "dependencies": { 1241 | "json-buffer": "3.0.1" 1242 | } 1243 | }, 1244 | "node_modules/levn": { 1245 | "version": "0.4.1", 1246 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1247 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1248 | "dev": true, 1249 | "license": "MIT", 1250 | "dependencies": { 1251 | "prelude-ls": "^1.2.1", 1252 | "type-check": "~0.4.0" 1253 | }, 1254 | "engines": { 1255 | "node": ">= 0.8.0" 1256 | } 1257 | }, 1258 | "node_modules/locate-path": { 1259 | "version": "6.0.0", 1260 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1261 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1262 | "dev": true, 1263 | "license": "MIT", 1264 | "dependencies": { 1265 | "p-locate": "^5.0.0" 1266 | }, 1267 | "engines": { 1268 | "node": ">=10" 1269 | }, 1270 | "funding": { 1271 | "url": "https://github.com/sponsors/sindresorhus" 1272 | } 1273 | }, 1274 | "node_modules/lodash.merge": { 1275 | "version": "4.6.2", 1276 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1277 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1278 | "dev": true, 1279 | "license": "MIT" 1280 | }, 1281 | "node_modules/minimatch": { 1282 | "version": "3.1.2", 1283 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1284 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1285 | "dev": true, 1286 | "license": "ISC", 1287 | "dependencies": { 1288 | "brace-expansion": "^1.1.7" 1289 | }, 1290 | "engines": { 1291 | "node": "*" 1292 | } 1293 | }, 1294 | "node_modules/ms": { 1295 | "version": "2.1.3", 1296 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1297 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1298 | "dev": true, 1299 | "license": "MIT" 1300 | }, 1301 | "node_modules/natural-compare": { 1302 | "version": "1.4.0", 1303 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1304 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1305 | "dev": true, 1306 | "license": "MIT" 1307 | }, 1308 | "node_modules/optionator": { 1309 | "version": "0.9.4", 1310 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 1311 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 1312 | "dev": true, 1313 | "license": "MIT", 1314 | "dependencies": { 1315 | "deep-is": "^0.1.3", 1316 | "fast-levenshtein": "^2.0.6", 1317 | "levn": "^0.4.1", 1318 | "prelude-ls": "^1.2.1", 1319 | "type-check": "^0.4.0", 1320 | "word-wrap": "^1.2.5" 1321 | }, 1322 | "engines": { 1323 | "node": ">= 0.8.0" 1324 | } 1325 | }, 1326 | "node_modules/p-limit": { 1327 | "version": "3.1.0", 1328 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1329 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1330 | "dev": true, 1331 | "license": "MIT", 1332 | "dependencies": { 1333 | "yocto-queue": "^0.1.0" 1334 | }, 1335 | "engines": { 1336 | "node": ">=10" 1337 | }, 1338 | "funding": { 1339 | "url": "https://github.com/sponsors/sindresorhus" 1340 | } 1341 | }, 1342 | "node_modules/p-locate": { 1343 | "version": "5.0.0", 1344 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1345 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1346 | "dev": true, 1347 | "license": "MIT", 1348 | "dependencies": { 1349 | "p-limit": "^3.0.2" 1350 | }, 1351 | "engines": { 1352 | "node": ">=10" 1353 | }, 1354 | "funding": { 1355 | "url": "https://github.com/sponsors/sindresorhus" 1356 | } 1357 | }, 1358 | "node_modules/parent-module": { 1359 | "version": "1.0.1", 1360 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1361 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1362 | "dev": true, 1363 | "license": "MIT", 1364 | "dependencies": { 1365 | "callsites": "^3.0.0" 1366 | }, 1367 | "engines": { 1368 | "node": ">=6" 1369 | } 1370 | }, 1371 | "node_modules/path-exists": { 1372 | "version": "4.0.0", 1373 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1374 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1375 | "dev": true, 1376 | "license": "MIT", 1377 | "engines": { 1378 | "node": ">=8" 1379 | } 1380 | }, 1381 | "node_modules/path-key": { 1382 | "version": "3.1.1", 1383 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1384 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1385 | "dev": true, 1386 | "license": "MIT", 1387 | "engines": { 1388 | "node": ">=8" 1389 | } 1390 | }, 1391 | "node_modules/picomatch": { 1392 | "version": "4.0.3", 1393 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", 1394 | "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", 1395 | "dev": true, 1396 | "license": "MIT", 1397 | "engines": { 1398 | "node": ">=12" 1399 | }, 1400 | "funding": { 1401 | "url": "https://github.com/sponsors/jonschlinkert" 1402 | } 1403 | }, 1404 | "node_modules/prelude-ls": { 1405 | "version": "1.2.1", 1406 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 1407 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 1408 | "dev": true, 1409 | "license": "MIT", 1410 | "engines": { 1411 | "node": ">= 0.8.0" 1412 | } 1413 | }, 1414 | "node_modules/punycode": { 1415 | "version": "2.3.1", 1416 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1417 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1418 | "dev": true, 1419 | "license": "MIT", 1420 | "engines": { 1421 | "node": ">=6" 1422 | } 1423 | }, 1424 | "node_modules/randombytes": { 1425 | "version": "2.1.0", 1426 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1427 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1428 | "dev": true, 1429 | "license": "MIT", 1430 | "dependencies": { 1431 | "safe-buffer": "^5.1.0" 1432 | } 1433 | }, 1434 | "node_modules/resolve-from": { 1435 | "version": "4.0.0", 1436 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1437 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1438 | "dev": true, 1439 | "license": "MIT", 1440 | "engines": { 1441 | "node": ">=4" 1442 | } 1443 | }, 1444 | "node_modules/rollup": { 1445 | "version": "4.46.2", 1446 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", 1447 | "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", 1448 | "dev": true, 1449 | "license": "MIT", 1450 | "dependencies": { 1451 | "@types/estree": "1.0.8" 1452 | }, 1453 | "bin": { 1454 | "rollup": "dist/bin/rollup" 1455 | }, 1456 | "engines": { 1457 | "node": ">=18.0.0", 1458 | "npm": ">=8.0.0" 1459 | }, 1460 | "optionalDependencies": { 1461 | "@rollup/rollup-android-arm-eabi": "4.46.2", 1462 | "@rollup/rollup-android-arm64": "4.46.2", 1463 | "@rollup/rollup-darwin-arm64": "4.46.2", 1464 | "@rollup/rollup-darwin-x64": "4.46.2", 1465 | "@rollup/rollup-freebsd-arm64": "4.46.2", 1466 | "@rollup/rollup-freebsd-x64": "4.46.2", 1467 | "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", 1468 | "@rollup/rollup-linux-arm-musleabihf": "4.46.2", 1469 | "@rollup/rollup-linux-arm64-gnu": "4.46.2", 1470 | "@rollup/rollup-linux-arm64-musl": "4.46.2", 1471 | "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", 1472 | "@rollup/rollup-linux-ppc64-gnu": "4.46.2", 1473 | "@rollup/rollup-linux-riscv64-gnu": "4.46.2", 1474 | "@rollup/rollup-linux-riscv64-musl": "4.46.2", 1475 | "@rollup/rollup-linux-s390x-gnu": "4.46.2", 1476 | "@rollup/rollup-linux-x64-gnu": "4.46.2", 1477 | "@rollup/rollup-linux-x64-musl": "4.46.2", 1478 | "@rollup/rollup-win32-arm64-msvc": "4.46.2", 1479 | "@rollup/rollup-win32-ia32-msvc": "4.46.2", 1480 | "@rollup/rollup-win32-x64-msvc": "4.46.2", 1481 | "fsevents": "~2.3.2" 1482 | } 1483 | }, 1484 | "node_modules/safe-buffer": { 1485 | "version": "5.2.1", 1486 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1487 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1488 | "dev": true, 1489 | "funding": [ 1490 | { 1491 | "type": "github", 1492 | "url": "https://github.com/sponsors/feross" 1493 | }, 1494 | { 1495 | "type": "patreon", 1496 | "url": "https://www.patreon.com/feross" 1497 | }, 1498 | { 1499 | "type": "consulting", 1500 | "url": "https://feross.org/support" 1501 | } 1502 | ], 1503 | "license": "MIT" 1504 | }, 1505 | "node_modules/serialize-javascript": { 1506 | "version": "6.0.2", 1507 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 1508 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 1509 | "dev": true, 1510 | "license": "BSD-3-Clause", 1511 | "dependencies": { 1512 | "randombytes": "^2.1.0" 1513 | } 1514 | }, 1515 | "node_modules/shebang-command": { 1516 | "version": "2.0.0", 1517 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1518 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1519 | "dev": true, 1520 | "license": "MIT", 1521 | "dependencies": { 1522 | "shebang-regex": "^3.0.0" 1523 | }, 1524 | "engines": { 1525 | "node": ">=8" 1526 | } 1527 | }, 1528 | "node_modules/shebang-regex": { 1529 | "version": "3.0.0", 1530 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1531 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1532 | "dev": true, 1533 | "license": "MIT", 1534 | "engines": { 1535 | "node": ">=8" 1536 | } 1537 | }, 1538 | "node_modules/smob": { 1539 | "version": "1.5.0", 1540 | "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", 1541 | "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", 1542 | "dev": true, 1543 | "license": "MIT" 1544 | }, 1545 | "node_modules/source-map": { 1546 | "version": "0.6.1", 1547 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1548 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1549 | "dev": true, 1550 | "license": "BSD-3-Clause", 1551 | "engines": { 1552 | "node": ">=0.10.0" 1553 | } 1554 | }, 1555 | "node_modules/source-map-support": { 1556 | "version": "0.5.21", 1557 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 1558 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 1559 | "dev": true, 1560 | "license": "MIT", 1561 | "dependencies": { 1562 | "buffer-from": "^1.0.0", 1563 | "source-map": "^0.6.0" 1564 | } 1565 | }, 1566 | "node_modules/strip-json-comments": { 1567 | "version": "3.1.1", 1568 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1569 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1570 | "dev": true, 1571 | "license": "MIT", 1572 | "engines": { 1573 | "node": ">=8" 1574 | }, 1575 | "funding": { 1576 | "url": "https://github.com/sponsors/sindresorhus" 1577 | } 1578 | }, 1579 | "node_modules/supports-color": { 1580 | "version": "7.2.0", 1581 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1582 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1583 | "dev": true, 1584 | "license": "MIT", 1585 | "dependencies": { 1586 | "has-flag": "^4.0.0" 1587 | }, 1588 | "engines": { 1589 | "node": ">=8" 1590 | } 1591 | }, 1592 | "node_modules/terser": { 1593 | "version": "5.43.1", 1594 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", 1595 | "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", 1596 | "dev": true, 1597 | "license": "BSD-2-Clause", 1598 | "dependencies": { 1599 | "@jridgewell/source-map": "^0.3.3", 1600 | "acorn": "^8.14.0", 1601 | "commander": "^2.20.0", 1602 | "source-map-support": "~0.5.20" 1603 | }, 1604 | "bin": { 1605 | "terser": "bin/terser" 1606 | }, 1607 | "engines": { 1608 | "node": ">=10" 1609 | } 1610 | }, 1611 | "node_modules/type-check": { 1612 | "version": "0.4.0", 1613 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1614 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1615 | "dev": true, 1616 | "license": "MIT", 1617 | "dependencies": { 1618 | "prelude-ls": "^1.2.1" 1619 | }, 1620 | "engines": { 1621 | "node": ">= 0.8.0" 1622 | } 1623 | }, 1624 | "node_modules/typescript": { 1625 | "version": "5.9.2", 1626 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", 1627 | "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", 1628 | "dev": true, 1629 | "license": "Apache-2.0", 1630 | "bin": { 1631 | "tsc": "bin/tsc", 1632 | "tsserver": "bin/tsserver" 1633 | }, 1634 | "engines": { 1635 | "node": ">=14.17" 1636 | } 1637 | }, 1638 | "node_modules/uri-js": { 1639 | "version": "4.4.1", 1640 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1641 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1642 | "dev": true, 1643 | "license": "BSD-2-Clause", 1644 | "dependencies": { 1645 | "punycode": "^2.1.0" 1646 | } 1647 | }, 1648 | "node_modules/which": { 1649 | "version": "2.0.2", 1650 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1651 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1652 | "dev": true, 1653 | "license": "ISC", 1654 | "dependencies": { 1655 | "isexe": "^2.0.0" 1656 | }, 1657 | "bin": { 1658 | "node-which": "bin/node-which" 1659 | }, 1660 | "engines": { 1661 | "node": ">= 8" 1662 | } 1663 | }, 1664 | "node_modules/word-wrap": { 1665 | "version": "1.2.5", 1666 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 1667 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 1668 | "dev": true, 1669 | "license": "MIT", 1670 | "engines": { 1671 | "node": ">=0.10.0" 1672 | } 1673 | }, 1674 | "node_modules/yocto-queue": { 1675 | "version": "0.1.0", 1676 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1677 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1678 | "dev": true, 1679 | "license": "MIT", 1680 | "engines": { 1681 | "node": ">=10" 1682 | }, 1683 | "funding": { 1684 | "url": "https://github.com/sponsors/sindresorhus" 1685 | } 1686 | } 1687 | } 1688 | } 1689 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kdbush", 3 | "version": "4.0.2", 4 | "description": "A very fast static 2D index for points based on kd-tree.", 5 | "type": "module", 6 | "main": "kdbush.js", 7 | "module": "index.js", 8 | "exports": "./index.js", 9 | "types": "index.d.ts", 10 | "sideEffects": false, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/mourner/kdbush.git" 14 | }, 15 | "devDependencies": { 16 | "@rollup/plugin-terser": "^0.4.4", 17 | "eslint": "^9.33.0", 18 | "eslint-config-mourner": "^4.1.0", 19 | "rollup": "^4.46.2", 20 | "typescript": "^5.9.2" 21 | }, 22 | "scripts": { 23 | "pretest": "eslint", 24 | "test": "tsc && node test.js", 25 | "bench": "node bench.js", 26 | "build": "rollup -c", 27 | "prepublishOnly": "npm run test && npm run build" 28 | }, 29 | "keywords": [ 30 | "index", 31 | "points", 32 | "kd-tree", 33 | "data structures", 34 | "algorithms", 35 | "spatial", 36 | "geometry" 37 | ], 38 | "files": [ 39 | "kdbush.js", 40 | "kdbush.min.js", 41 | "index.js", 42 | "index.d.ts" 43 | ], 44 | "author": "Vladimir Agafonkin", 45 | "license": "ISC" 46 | } 47 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import terser from '@rollup/plugin-terser'; 2 | 3 | const config = (file, plugins) => ({ 4 | input: 'index.js', 5 | output: { 6 | name: 'KDBush', 7 | format: 'umd', 8 | indent: false, 9 | file 10 | }, 11 | plugins 12 | }); 13 | 14 | export default [ 15 | config('kdbush.js', []), 16 | config('kdbush.min.js', [terser()]) 17 | ]; 18 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | import KDBush from './index.js'; 2 | import test from 'node:test'; 3 | import assert from 'node:assert/strict'; 4 | 5 | /* eslint @stylistic/comma-spacing: 0 */ 6 | 7 | const points = [ 8 | [54,1],[97,21],[65,35],[33,54],[95,39],[54,3],[53,54],[84,72],[33,34],[43,15],[52,83],[81,23],[1,61],[38,74], 9 | [11,91],[24,56],[90,31],[25,57],[46,61],[29,69],[49,60],[4,98],[71,15],[60,25],[38,84],[52,38],[94,51],[13,25], 10 | [77,73],[88,87],[6,27],[58,22],[53,28],[27,91],[96,98],[93,14],[22,93],[45,94],[18,28],[35,15],[19,81],[20,81], 11 | [67,53],[43,3],[47,66],[48,34],[46,12],[32,38],[43,12],[39,94],[88,62],[66,14],[84,30],[72,81],[41,92],[26,4], 12 | [6,76],[47,21],[57,70],[71,82],[50,68],[96,18],[40,31],[78,53],[71,90],[32,14],[55,6],[32,88],[62,32],[21,67], 13 | [73,81],[44,64],[29,50],[70,5],[6,22],[68,3],[11,23],[20,42],[21,73],[63,86],[9,40],[99,2],[99,76],[56,77], 14 | [83,6],[21,72],[78,30],[75,53],[41,11],[95,20],[30,38],[96,82],[65,48],[33,18],[87,28],[10,10],[40,34], 15 | [10,20],[47,29],[46,78]]; 16 | 17 | const ids = [ 18 | 97,74,95,30,77,38,76,27,80,55,72,90,88,48,43,46,65,39,62,93,9,96,47,8,3,12,15,14,21,41,36,40,69,56,85,78,17,71,44, 19 | 19,18,13,99,24,67,33,37,49,54,57,98,45,23,31,66,68,0,32,5,51,75,73,84,35,81,22,61,89,1,11,86,52,94,16,2,6,25,92, 20 | 42,20,60,58,83,79,64,10,59,53,26,87,4,63,50,7,28,82,70,29,34,91]; 21 | 22 | const coords = [ 23 | 10,20,6,22,10,10,6,27,20,42,18,28,11,23,13,25,9,40,26,4,29,50,30,38,41,11,43,12,43,3,46,12,32,14,35,15,40,31,33,18, 24 | 43,15,40,34,32,38,33,34,33,54,1,61,24,56,11,91,4,98,20,81,22,93,19,81,21,67,6,76,21,72,21,73,25,57,44,64,47,66,29, 25 | 69,46,61,38,74,46,78,38,84,32,88,27,91,45,94,39,94,41,92,47,21,47,29,48,34,60,25,58,22,55,6,62,32,54,1,53,28,54,3, 26 | 66,14,68,3,70,5,83,6,93,14,99,2,71,15,96,18,95,20,97,21,81,23,78,30,84,30,87,28,90,31,65,35,53,54,52,38,65,48,67, 27 | 53,49,60,50,68,57,70,56,77,63,86,71,90,52,83,71,82,72,81,94,51,75,53,95,39,78,53,88,62,84,72,77,73,99,76,73,81,88, 28 | 87,96,98,96,82]; 29 | 30 | function makeIndex(ArrayBufferType = ArrayBuffer) { 31 | const index = new KDBush(points.length, 10, undefined, ArrayBufferType); 32 | for (const [x, y] of points) index.add(x, y); 33 | return index.finish(); 34 | } 35 | 36 | test('creates an index', () => { 37 | const index = makeIndex(); 38 | 39 | assert.deepEqual(Array.from(index.ids), ids, 'ids are kd-sorted'); 40 | assert.deepEqual(Array.from(index.coords), coords, 'coords are kd-sorted'); 41 | }); 42 | 43 | test('range search', () => { 44 | const index = makeIndex(); 45 | 46 | const result = index.range(20, 30, 50, 70); 47 | 48 | assert.deepEqual(result, [60,20,45,3,17,71,44,19,18,15,69,90,62,96,47,8,77,72], 'returns ids'); 49 | 50 | for (const id of result) { 51 | const p = points[id]; 52 | if (p[0] < 20 || p[0] > 50 || p[1] < 30 || p[1] > 70) 53 | assert.fail('result point in range'); 54 | } 55 | // result points in range 56 | 57 | for (const id of ids) { 58 | const p = points[id]; 59 | if (result.indexOf(id) < 0 && p[0] >= 20 && p[0] <= 50 && p[1] >= 30 && p[1] <= 70) 60 | assert.fail('outside point not in range'); 61 | } 62 | // outside points not in range 63 | }); 64 | 65 | test('radius search', () => { 66 | const index = makeIndex(); 67 | 68 | const qp = [50, 50]; 69 | const r = 20; 70 | const r2 = 20 * 20; 71 | 72 | const result = index.within(qp[0], qp[1], r); 73 | 74 | assert.deepEqual(result, [60,6,25,92,42,20,45,3,71,44,18,96], 'returns ids'); 75 | 76 | for (const id of result) { 77 | const p = points[id]; 78 | if (sqDist(p, qp) > r2) assert.fail('result point in range'); 79 | } 80 | // result points in range 81 | 82 | for (const id of ids) { 83 | const p = points[id]; 84 | if (result.indexOf(id) < 0 && sqDist(p, qp) <= r2) 85 | assert.fail('outside point not in range'); 86 | } 87 | // outside points not in range 88 | }); 89 | 90 | test('reconstructs an index from array buffer', () => { 91 | const index = makeIndex(); 92 | const index2 = KDBush.from(index.data); 93 | 94 | assert.deepEqual(index, index2); 95 | }); 96 | 97 | test('throws an error if added less items than the index size', () => { 98 | assert.throws(() => { 99 | const index = new KDBush(points.length); 100 | index.finish(); 101 | }); 102 | }); 103 | 104 | test('throws an error if searching before indexing', () => { 105 | const index = new KDBush(points.length); 106 | assert.throws(() => { 107 | index.range(0, 0, 20, 20); 108 | }); 109 | assert.throws(() => { 110 | index.within(10, 10, 20); 111 | }); 112 | }); 113 | 114 | test('does not complain about zero items', () => { 115 | assert.doesNotThrow(() => { 116 | const index = new KDBush(0); 117 | index.finish(); 118 | assert.deepEqual(index.range(0, 0, 10, 10), []); 119 | assert.deepEqual(index.within(0, 0, 10), []); 120 | }); 121 | }); 122 | 123 | test('creates an index using SharedArrayBuffer', () => { 124 | const index = makeIndex(SharedArrayBuffer); 125 | assert(index.data instanceof SharedArrayBuffer); 126 | }); 127 | 128 | test('reconstructs an index from a SharedArrayBuffer', () => { 129 | const index = makeIndex(SharedArrayBuffer); 130 | const index2 = KDBush.from(index.data); 131 | assert.deepEqual(index, index2); 132 | }); 133 | 134 | function sqDist(a, b) { 135 | const dx = a[0] - b[0]; 136 | const dy = a[1] - b[1]; 137 | return dx * dx + dy * dy; 138 | } 139 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "checkJs": true, 5 | "strict": true, 6 | "emitDeclarationOnly": true, 7 | "declaration": true, 8 | "target": "es2017" 9 | }, 10 | "files": [ 11 | "index.js" 12 | ] 13 | } 14 | --------------------------------------------------------------------------------