├── src ├── index.js ├── root.js ├── quad.js ├── x.js ├── y.js ├── size.js ├── data.js ├── extent.js ├── visit.js ├── visitAfter.js ├── cover.js ├── find.js ├── remove.js ├── quadtree.js └── add.js ├── .gitignore ├── test ├── .eslintrc.json ├── size-test.js ├── data-test.js ├── benchmark.js ├── quadtree-test.js ├── x-test.js ├── y-test.js ├── find-test.js ├── copy-test.js ├── extent-test.js ├── visit-test.js ├── addAll-test.js ├── add-test.js ├── remove-test.js └── cover-test.js ├── .eslintrc.json ├── .github ├── eslint.json └── workflows │ └── node.js.yml ├── LICENSE ├── README.md ├── rollup.config.js ├── package.json └── yarn.lock /src/index.js: -------------------------------------------------------------------------------- 1 | export {default as quadtree} from "./quadtree.js"; 2 | -------------------------------------------------------------------------------- /src/root.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | return this._root; 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-workspace 2 | .DS_Store 3 | dist/ 4 | node_modules 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /src/quad.js: -------------------------------------------------------------------------------- 1 | export default function(node, x0, y0, x1, y1) { 2 | this.node = node; 3 | this.x0 = x0; 4 | this.y0 = y0; 5 | this.x1 = x1; 6 | this.y1 = y1; 7 | } 8 | -------------------------------------------------------------------------------- /src/x.js: -------------------------------------------------------------------------------- 1 | export function defaultX(d) { 2 | return d[0]; 3 | } 4 | 5 | export default function(_) { 6 | return arguments.length ? (this._x = _, this) : this._x; 7 | } 8 | -------------------------------------------------------------------------------- /src/y.js: -------------------------------------------------------------------------------- 1 | export function defaultY(d) { 2 | return d[1]; 3 | } 4 | 5 | export default function(_) { 6 | return arguments.length ? (this._y = _, this) : this._y; 7 | } 8 | -------------------------------------------------------------------------------- /src/size.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | var size = 0; 3 | this.visit(function(node) { 4 | if (!node.length) do ++size; while (node = node.next) 5 | }); 6 | return size; 7 | } 8 | -------------------------------------------------------------------------------- /src/data.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | var data = []; 3 | this.visit(function(node) { 4 | if (!node.length) do data.push(node.data); while (node = node.next) 5 | }); 6 | return data; 7 | } 8 | -------------------------------------------------------------------------------- /src/extent.js: -------------------------------------------------------------------------------- 1 | export default function(_) { 2 | return arguments.length 3 | ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) 4 | : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; 5 | } 6 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaVersion": 8 6 | }, 7 | "env": { 8 | "node": true, 9 | "mocha": true 10 | }, 11 | "rules": { 12 | "no-sparse-arrays": 0 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parserOptions": { 4 | "sourceType": "module", 5 | "ecmaVersion": 8 6 | }, 7 | "env": { 8 | "es6": true 9 | }, 10 | "rules": { 11 | "no-cond-assign": 0, 12 | "no-constant-condition": 0 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "eslint-compact", 5 | "pattern": [ 6 | { 7 | "regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$", 8 | "file": 1, 9 | "line": 2, 10 | "column": 3, 11 | "severity": 4, 12 | "message": 5, 13 | "code": 6 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /test/size-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.size() returns the number of points in the quadtree", () => { 5 | const q = quadtree(); 6 | assert.strictEqual(q.size(), 0); 7 | q.add([0, 0]).add([1, 2]); 8 | assert.strictEqual(q.size(), 2); 9 | }); 10 | 11 | it("quadtree.size() correctly counts coincident nodes", () => { 12 | const q = quadtree(); 13 | q.add([0, 0]).add([0, 0]); 14 | assert.strictEqual(q.size(), 2); 15 | }); 16 | -------------------------------------------------------------------------------- /test/data-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.data() returns an array of data in the quadtree", () => { 5 | const q = quadtree(); 6 | assert.deepStrictEqual(q.data(), []); 7 | q.add([0, 0]).add([1, 2]); 8 | assert.deepStrictEqual(q.data(), [[0, 0], [1, 2]]); 9 | }); 10 | 11 | it("quadtree.data() correctly handles coincident nodes", () => { 12 | const q = quadtree(); 13 | q.add([0, 0]).add([0, 0]); 14 | assert.deepStrictEqual(q.data(), [[0, 0], [0, 0]]); 15 | }); 16 | -------------------------------------------------------------------------------- /src/visit.js: -------------------------------------------------------------------------------- 1 | import Quad from "./quad.js"; 2 | 3 | export default function(callback) { 4 | var quads = [], q, node = this._root, child, x0, y0, x1, y1; 5 | if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); 6 | while (q = quads.pop()) { 7 | if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { 8 | var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; 9 | if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); 10 | if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); 11 | if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); 12 | if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); 13 | } 14 | } 15 | return this; 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2021 Mike Bostock 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose 4 | with or without fee is hereby granted, provided that the above copyright notice 5 | and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 9 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 11 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 12 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 13 | THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 2 | 3 | name: Node.js CI 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | pull_request: 9 | branches: [ main ] 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [14.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: yarn --frozen-lockfile 27 | - run: | 28 | echo ::add-matcher::.github/eslint.json 29 | yarn run eslint src test --format=compact 30 | - run: yarn test 31 | -------------------------------------------------------------------------------- /src/visitAfter.js: -------------------------------------------------------------------------------- 1 | import Quad from "./quad.js"; 2 | 3 | export default function(callback) { 4 | var quads = [], next = [], q; 5 | if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); 6 | while (q = quads.pop()) { 7 | var node = q.node; 8 | if (node.length) { 9 | var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; 10 | if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); 11 | if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); 12 | if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); 13 | if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); 14 | } 15 | next.push(q); 16 | } 17 | while (q = next.pop()) { 18 | callback(q.node, q.x0, q.y0, q.x1, q.y1); 19 | } 20 | return this; 21 | } 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # d3-quadtree 2 | 3 | 4 | 5 | A [quadtree](https://en.wikipedia.org/wiki/Quadtree) recursively partitions two-dimensional space into squares, dividing each square into four equally-sized squares. Each distinct point exists in a unique leaf node; coincident points are represented by a linked list. Quadtrees can accelerate various spatial operations, such as the [Barnes–Hut approximation](https://en.wikipedia.org/wiki/Barnes–Hut_simulation) for computing many-body forces, collision detection, and searching for nearby points. 6 | 7 | ## Resources 8 | 9 | - [Documentation](https://d3js.org/d3-quadtree) 10 | - [Examples](https://observablehq.com/collection/@d3/d3-quadtree) 11 | - [Releases](https://github.com/d3/d3-quadtree/releases) 12 | - [Getting help](https://d3js.org/community) 13 | -------------------------------------------------------------------------------- /test/benchmark.js: -------------------------------------------------------------------------------- 1 | import {quadtree} from "../src/index.js"; 2 | 3 | const n = 1000000; 4 | const points1 = new Array(n); 5 | const points2 = new Array(n); 6 | 7 | for (let j = 0; j < n; ++j) { 8 | points1[j] = [Math.random() * 99, Math.random() * 99]; 9 | } 10 | 11 | for (let j = 0; j < n; ++j) { 12 | points2[j] = [points1[j][0] + Math.random(), points1[j][1] + Math.random()]; 13 | } 14 | 15 | function time(message, run) { 16 | const [starts, startns] = process.hrtime(); 17 | run(); 18 | const [ends, endns] = process.hrtime(); 19 | console.log(message, Math.round((ends - starts) * 1e3 + (endns - startns) / 1e6)); 20 | } 21 | 22 | let root; 23 | 24 | time("create", () => { 25 | root = quadtree().extent([[0, 0], [100, 100]]).addAll(points1); 26 | }); 27 | 28 | time("iterate", () => { 29 | root.visit(() => {}); 30 | }); 31 | 32 | time("update", () => { 33 | for (let j = 0; j < n; ++j) { 34 | root.remove(points1[j]); 35 | root.add(points2[j]); 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /test/quadtree-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree() creates an empty quadtree", () => { 5 | const q = quadtree(); 6 | assert(q instanceof quadtree); 7 | assert.strictEqual(q.visit(function() { throw new Error; }), q); 8 | assert.strictEqual(q.size(), 0); 9 | assert.strictEqual(q.extent(), undefined); 10 | assert.strictEqual(q.root(), undefined); 11 | assert.deepStrictEqual(q.data(), []); 12 | }); 13 | 14 | it("quadtree(nodes) is equivalent to quadtree().addAll(nodes)", () => { 15 | const q = quadtree([[0, 0], [1, 1]]); 16 | assert(q instanceof quadtree); 17 | assert.deepStrictEqual(q.root(), [{data: [0, 0]},,, {data: [1, 1]}]); 18 | }); 19 | 20 | it("quadtree(nodes, x, y) is equivalent to quadtree().x(x).y(y).addAll(nodes)", () => { 21 | const q = quadtree([{x: 0, y: 0}, {x: 1, y: 1}], function(d) { return d.x; }, function(d) { return d.y; }); 22 | assert(q instanceof quadtree); 23 | assert.deepStrictEqual(q.root(), [{data: {x: 0, y: 0}},,, {data: {x: 1, y: 1}}]); 24 | }); 25 | -------------------------------------------------------------------------------- /test/x-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.x(x) sets the x-accessor used by quadtree.add", () => { 5 | const q = quadtree().x(x).add({x: 1, 1: 2}); 6 | assert.deepStrictEqual(q.extent(), [[1, 2], [2, 3]]); 7 | assert.deepStrictEqual(q.root(), {data: {x: 1, 1: 2}}); 8 | }); 9 | 10 | it("quadtree.x(x) sets the x-accessor used by quadtree.addAll", () => { 11 | const q = quadtree().x(x).addAll([{x: 1, 1: 2}]); 12 | assert.deepStrictEqual(q.extent(), [[1, 2], [2, 3]]); 13 | assert.deepStrictEqual(q.root(), {data: {x: 1, 1: 2}}); 14 | }); 15 | 16 | it("quadtree.x(x) sets the x-accessor used by quadtree.remove", () => { 17 | const p0 = {x: 0, 1: 1}; 18 | const p1 = {x: 1, 1: 2}; 19 | const q = quadtree().x(x); 20 | assert.deepStrictEqual(q.add(p0).root(), {data: {x: 0, 1: 1}}); 21 | assert.deepStrictEqual(q.add(p1).root(), [{data: {x: 0, 1: 1}},,, {data: {x: 1, 1: 2}}]); 22 | assert.deepStrictEqual(q.remove(p1).root(), {data: {x: 0, 1: 1}}); 23 | assert.strictEqual(q.remove(p0).root(), undefined); 24 | }); 25 | 26 | function x(d) { 27 | return d.x; 28 | } 29 | -------------------------------------------------------------------------------- /test/y-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.y(y) sets the y-accessor used by quadtree.add", () => { 5 | const q = quadtree().y(y).add({0: 1, y: 2}); 6 | assert.deepStrictEqual(q.extent(), [[1, 2], [2, 3]]); 7 | assert.deepStrictEqual(q.root(), {data: {0: 1, y: 2}}); 8 | }); 9 | 10 | it("quadtree.y(y) sets the y-accessor used by quadtree.addAll", () => { 11 | const q = quadtree().y(y).addAll([{0: 1, y: 2}]); 12 | assert.deepStrictEqual(q.extent(), [[1, 2], [2, 3]]); 13 | assert.deepStrictEqual(q.root(), {data: {0: 1, y: 2}}); 14 | }); 15 | 16 | it("quadtree.y(y) sets the y-accessor used by quadtree.remove", () => { 17 | const p0 = {0: 0, y: 1}; 18 | const p1 = {0: 1, y: 2}; 19 | const q = quadtree().y(y); 20 | assert.deepStrictEqual(q.add(p0).root(), {data: {0: 0, y: 1}}); 21 | assert.deepStrictEqual(q.add(p1).root(), [{data: {0: 0, y: 1}},,, {data: {0: 1, y: 2}}]); 22 | assert.deepStrictEqual(q.remove(p1).root(), {data: {0: 0, y: 1}}); 23 | assert.strictEqual(q.remove(p0).root(), undefined); 24 | }); 25 | 26 | function y(d) { 27 | return d.y; 28 | } 29 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import {readFileSync} from "fs"; 2 | import {terser} from "rollup-plugin-terser"; 3 | import * as meta from "./package.json"; 4 | 5 | // Extract copyrights from the LICENSE. 6 | const copyright = readFileSync("./LICENSE", "utf-8") 7 | .split(/\n/g) 8 | .filter(line => /^Copyright\s+/.test(line)) 9 | .map(line => line.replace(/^Copyright\s+/, "")) 10 | .join(", "); 11 | 12 | const config = { 13 | input: "src/index.js", 14 | external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)), 15 | output: { 16 | file: `dist/${meta.name}.js`, 17 | name: "d3", 18 | format: "umd", 19 | indent: false, 20 | extend: true, 21 | banner: `// ${meta.homepage} v${meta.version} Copyright ${copyright}`, 22 | globals: Object.assign({}, ...Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)).map(key => ({[key]: "d3"}))) 23 | }, 24 | plugins: [] 25 | }; 26 | 27 | export default [ 28 | config, 29 | { 30 | ...config, 31 | output: { 32 | ...config.output, 33 | file: `dist/${meta.name}.min.js` 34 | }, 35 | plugins: [ 36 | ...config.plugins, 37 | terser({ 38 | output: { 39 | preamble: config.output.banner 40 | } 41 | }) 42 | ] 43 | } 44 | ]; 45 | -------------------------------------------------------------------------------- /src/cover.js: -------------------------------------------------------------------------------- 1 | export default function(x, y) { 2 | if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points 3 | 4 | var x0 = this._x0, 5 | y0 = this._y0, 6 | x1 = this._x1, 7 | y1 = this._y1; 8 | 9 | // If the quadtree has no extent, initialize them. 10 | // Integer extent are necessary so that if we later double the extent, 11 | // the existing quadrant boundaries don’t change due to floating point error! 12 | if (isNaN(x0)) { 13 | x1 = (x0 = Math.floor(x)) + 1; 14 | y1 = (y0 = Math.floor(y)) + 1; 15 | } 16 | 17 | // Otherwise, double repeatedly to cover. 18 | else { 19 | var z = x1 - x0 || 1, 20 | node = this._root, 21 | parent, 22 | i; 23 | 24 | while (x0 > x || x >= x1 || y0 > y || y >= y1) { 25 | i = (y < y0) << 1 | (x < x0); 26 | parent = new Array(4), parent[i] = node, node = parent, z *= 2; 27 | switch (i) { 28 | case 0: x1 = x0 + z, y1 = y0 + z; break; 29 | case 1: x0 = x1 - z, y1 = y0 + z; break; 30 | case 2: x1 = x0 + z, y0 = y1 - z; break; 31 | case 3: x0 = x1 - z, y0 = y1 - z; break; 32 | } 33 | } 34 | 35 | if (this._root && this._root.length) this._root = node; 36 | } 37 | 38 | this._x0 = x0; 39 | this._y0 = y0; 40 | this._x1 = x1; 41 | this._y1 = y1; 42 | return this; 43 | } 44 | -------------------------------------------------------------------------------- /test/find-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.find(x, y) returns the closest point to the given [x, y]", () => { 5 | const dx = 17; 6 | const dy = 17; 7 | const q = quadtree(); 8 | for (let i = 0, n = dx * dy; i < n; ++i) { q.add([i % dx, i / dx | 0]); } 9 | assert.deepStrictEqual(q.find( 0.1, 0.1), [ 0, 0]); 10 | assert.deepStrictEqual(q.find( 7.1, 7.1), [ 7, 7]); 11 | assert.deepStrictEqual(q.find( 0.1, 15.9), [ 0, 16]); 12 | assert.deepStrictEqual(q.find(15.9, 15.9), [16, 16]); 13 | }); 14 | 15 | it("quadtree.find(x, y, radius) returns the closest point within the search radius to the given [x, y]", () => { 16 | const q = quadtree([[0, 0], [100, 0], [0, 100], [100, 100]]); 17 | assert.deepStrictEqual(q.find(20, 20, Infinity), [0, 0]); 18 | assert.deepStrictEqual(q.find(20, 20, 20 * Math.SQRT2 + 1e-6), [0, 0]); 19 | assert.strictEqual(q.find(20, 20, 20 * Math.SQRT2 - 1e-6), undefined); 20 | assert.deepStrictEqual(q.find(0, 20, 20 + 1e-6), [0, 0]); 21 | assert.strictEqual(q.find(0, 20, 20 - 1e-6), undefined); 22 | assert.deepStrictEqual(q.find(20, 0, 20 + 1e-6), [0, 0]); 23 | assert.strictEqual(q.find(20, 0, 20 - 1e-6), undefined); 24 | }); 25 | 26 | it("quadtree.find(x, y, null) treats the given radius as Infinity", () => { 27 | const q = quadtree([[0, 0], [100, 0], [0, 100], [100, 100]]); 28 | assert.deepStrictEqual(q.find(20, 20, null), [0, 0]); 29 | assert.deepStrictEqual(q.find(20, 20, undefined), [0, 0]); 30 | }); 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3-quadtree", 3 | "version": "3.0.1", 4 | "description": "Two-dimensional recursive spatial subdivision.", 5 | "homepage": "https://d3js.org/d3-quadtree/", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/d3/d3-quadtree.git" 9 | }, 10 | "keywords": [ 11 | "d3", 12 | "d3-module", 13 | "quadtree" 14 | ], 15 | "license": "ISC", 16 | "author": { 17 | "name": "Mike Bostock", 18 | "url": "http://bost.ocks.org/mike" 19 | }, 20 | "type": "module", 21 | "files": [ 22 | "dist/**/*.js", 23 | "src/**/*.js" 24 | ], 25 | "module": "src/index.js", 26 | "main": "src/index.js", 27 | "jsdelivr": "dist/d3-quadtree.min.js", 28 | "unpkg": "dist/d3-quadtree.min.js", 29 | "exports": { 30 | "umd": "./dist/d3-quadtree.min.js", 31 | "default": "./src/index.js" 32 | }, 33 | "sideEffects": false, 34 | "devDependencies": { 35 | "d3-array": "1 - 2", 36 | "eslint": "7", 37 | "mocha": "8", 38 | "rollup": "2", 39 | "rollup-plugin-terser": "7" 40 | }, 41 | "scripts": { 42 | "test": "mocha 'test/**/*-test.js' && eslint src test", 43 | "prepublishOnly": "rm -rf dist && yarn test && rollup -c", 44 | "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -" 45 | }, 46 | "engines": { 47 | "node": ">=12" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/copy-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.copy() returns a copy of this quadtree", () => { 5 | const q0 = quadtree().addAll([[0, 0], [1, 0], [0, 1], [1, 1]]); 6 | assert.deepStrictEqual(q0.copy(), q0); 7 | }); 8 | 9 | it("quadtree.copy() isolates changes to the extent", () => { 10 | const q0 = quadtree().extent([[0, 0], [1, 1]]); 11 | const q1 = q0.copy(); 12 | q0.add([2, 2]); 13 | assert.deepStrictEqual(q1.extent(), [[0, 0], [2, 2]]); 14 | q1.add([-1, -1]); 15 | assert.deepStrictEqual(q0.extent(), [[0, 0], [4, 4]]); 16 | }); 17 | 18 | it("quadtree.copy() isolates changes to the root when a leaf", () => { 19 | const q0 = quadtree().extent([[0, 0], [1, 1]]); 20 | const q1 = q0.copy(); 21 | const p0 = [2, 2]; 22 | q0.add(p0); 23 | assert.strictEqual(q1.root(), undefined); 24 | const q2 = q0.copy(); 25 | assert.deepStrictEqual(q0.root(), {data: [2, 2]}); 26 | assert.deepStrictEqual(q2.root(), {data: [2, 2]}); 27 | assert.strictEqual(q0.remove(p0), q0); 28 | assert.strictEqual(q0.root(), undefined); 29 | assert.deepStrictEqual(q2.root(), {data: [2, 2]}); 30 | }); 31 | 32 | it("quadtree.copy() isolates changes to the root when not a leaf", () => { 33 | const p0 = [1, 1]; 34 | const p1 = [2, 2]; 35 | const p2 = [3, 3]; 36 | const q0 = quadtree().extent([[0, 0], [4, 4]]).addAll([p0, p1]); 37 | const q1 = q0.copy(); 38 | q0.add(p2); 39 | assert.deepStrictEqual(q0.extent(), [[0, 0], [8, 8]]); 40 | assert.deepStrictEqual(q0.root(), [[{data: [1, 1]},,, [{data: [2, 2]},,, {data: [3, 3]}]],,,, ]); 41 | assert.deepStrictEqual(q1.extent(), [[0, 0], [8, 8]]); 42 | assert.deepStrictEqual(q1.root(), [[{data: [1, 1]},,, {data: [2, 2]}],,,, ]); 43 | const q3 = q0.copy(); 44 | q0.remove(p2); 45 | assert.deepStrictEqual(q3.extent(), [[0, 0], [8, 8]]); 46 | assert.deepStrictEqual(q3.root(), [[{data: [1, 1]},,, [{data: [2, 2]},,, {data: [3, 3]}]],,,, ]); 47 | }); 48 | -------------------------------------------------------------------------------- /src/find.js: -------------------------------------------------------------------------------- 1 | import Quad from "./quad.js"; 2 | 3 | export default function(x, y, radius) { 4 | var data, 5 | x0 = this._x0, 6 | y0 = this._y0, 7 | x1, 8 | y1, 9 | x2, 10 | y2, 11 | x3 = this._x1, 12 | y3 = this._y1, 13 | quads = [], 14 | node = this._root, 15 | q, 16 | i; 17 | 18 | if (node) quads.push(new Quad(node, x0, y0, x3, y3)); 19 | if (radius == null) radius = Infinity; 20 | else { 21 | x0 = x - radius, y0 = y - radius; 22 | x3 = x + radius, y3 = y + radius; 23 | radius *= radius; 24 | } 25 | 26 | while (q = quads.pop()) { 27 | 28 | // Stop searching if this quadrant can’t contain a closer node. 29 | if (!(node = q.node) 30 | || (x1 = q.x0) > x3 31 | || (y1 = q.y0) > y3 32 | || (x2 = q.x1) < x0 33 | || (y2 = q.y1) < y0) continue; 34 | 35 | // Bisect the current quadrant. 36 | if (node.length) { 37 | var xm = (x1 + x2) / 2, 38 | ym = (y1 + y2) / 2; 39 | 40 | quads.push( 41 | new Quad(node[3], xm, ym, x2, y2), 42 | new Quad(node[2], x1, ym, xm, y2), 43 | new Quad(node[1], xm, y1, x2, ym), 44 | new Quad(node[0], x1, y1, xm, ym) 45 | ); 46 | 47 | // Visit the closest quadrant first. 48 | if (i = (y >= ym) << 1 | (x >= xm)) { 49 | q = quads[quads.length - 1]; 50 | quads[quads.length - 1] = quads[quads.length - 1 - i]; 51 | quads[quads.length - 1 - i] = q; 52 | } 53 | } 54 | 55 | // Visit this point. (Visiting coincident points isn’t necessary!) 56 | else { 57 | var dx = x - +this._x.call(null, node.data), 58 | dy = y - +this._y.call(null, node.data), 59 | d2 = dx * dx + dy * dy; 60 | if (d2 < radius) { 61 | var d = Math.sqrt(radius = d2); 62 | x0 = x - d, y0 = y - d; 63 | x3 = x + d, y3 = y + d; 64 | data = node.data; 65 | } 66 | } 67 | } 68 | 69 | return data; 70 | } 71 | -------------------------------------------------------------------------------- /src/remove.js: -------------------------------------------------------------------------------- 1 | export default function(d) { 2 | if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points 3 | 4 | var parent, 5 | node = this._root, 6 | retainer, 7 | previous, 8 | next, 9 | x0 = this._x0, 10 | y0 = this._y0, 11 | x1 = this._x1, 12 | y1 = this._y1, 13 | x, 14 | y, 15 | xm, 16 | ym, 17 | right, 18 | bottom, 19 | i, 20 | j; 21 | 22 | // If the tree is empty, initialize the root as a leaf. 23 | if (!node) return this; 24 | 25 | // Find the leaf node for the point. 26 | // While descending, also retain the deepest parent with a non-removed sibling. 27 | if (node.length) while (true) { 28 | if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; 29 | if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; 30 | if (!(parent = node, node = node[i = bottom << 1 | right])) return this; 31 | if (!node.length) break; 32 | if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; 33 | } 34 | 35 | // Find the point to remove. 36 | while (node.data !== d) if (!(previous = node, node = node.next)) return this; 37 | if (next = node.next) delete node.next; 38 | 39 | // If there are multiple coincident points, remove just the point. 40 | if (previous) return (next ? previous.next = next : delete previous.next), this; 41 | 42 | // If this is the root point, remove it. 43 | if (!parent) return this._root = next, this; 44 | 45 | // Remove this leaf. 46 | next ? parent[i] = next : delete parent[i]; 47 | 48 | // If the parent now contains exactly one leaf, collapse superfluous parents. 49 | if ((node = parent[0] || parent[1] || parent[2] || parent[3]) 50 | && node === (parent[3] || parent[2] || parent[1] || parent[0]) 51 | && !node.length) { 52 | if (retainer) retainer[j] = node; 53 | else this._root = node; 54 | } 55 | 56 | return this; 57 | } 58 | 59 | export function removeAll(data) { 60 | for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); 61 | return this; 62 | } 63 | -------------------------------------------------------------------------------- /test/extent-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.extent(extent) extends the extent", () => { 5 | assert.deepStrictEqual(quadtree().extent([[0, 1], [2, 6]]).extent(), [[0, 1], [8, 9]]); 6 | }); 7 | 8 | it("quadtree.extent() can be inferred by quadtree.cover", () => { 9 | const q = quadtree(); 10 | assert.deepStrictEqual(q.cover(0, 0).extent(), [[0, 0], [1, 1]]); 11 | assert.deepStrictEqual(q.cover(2, 4).extent(), [[0, 0], [8, 8]]); 12 | }); 13 | 14 | it("quadtree.extent() can be inferred by quadtree.add", () => { 15 | const q = quadtree(); 16 | q.add([0, 0]); 17 | assert.deepStrictEqual(q.extent(), [[0, 0], [1, 1]]); 18 | q.add([2, 4]); 19 | assert.deepStrictEqual(q.extent(), [[0, 0], [8, 8]]); 20 | }); 21 | 22 | it("quadtree.extent(extent) squarifies and centers the specified extent", () => { 23 | assert.deepStrictEqual(quadtree().extent([[0, 1], [2, 6]]).extent(), [[0, 1], [8, 9]]); 24 | }); 25 | 26 | it("quadtree.extent(extent) ignores invalid extents", () => { 27 | assert.strictEqual(quadtree().extent([[1, NaN], [NaN, 0]]).extent(), undefined); 28 | assert.strictEqual(quadtree().extent([[NaN, 1], [0, NaN]]).extent(), undefined); 29 | assert.strictEqual(quadtree().extent([[NaN, NaN], [NaN, NaN]]).extent(), undefined); 30 | }); 31 | 32 | it("quadtree.extent(extent) flips inverted extents", () => { 33 | assert.deepStrictEqual(quadtree().extent([[1, 1], [0, 0]]).extent(), [[0, 0], [2, 2]]); 34 | }); 35 | 36 | it("quadtree.extent(extent) tolerates partially-valid extents", () => { 37 | assert.deepStrictEqual(quadtree().extent([[NaN, 0], [1, 1]]).extent(), [[1, 1], [2, 2]]); 38 | assert.deepStrictEqual(quadtree().extent([[0, NaN], [1, 1]]).extent(), [[1, 1], [2, 2]]); 39 | assert.deepStrictEqual(quadtree().extent([[0, 0], [NaN, 1]]).extent(), [[0, 0], [1, 1]]); 40 | assert.deepStrictEqual(quadtree().extent([[0, 0], [1, NaN]]).extent(), [[0, 0], [1, 1]]); 41 | }); 42 | 43 | it("quadtree.extent(extent) allows trivial extents", () => { 44 | assert.deepStrictEqual(quadtree().extent([[0, 0], [0, 0]]).extent(), [[0, 0], [1, 1]]); 45 | assert.deepStrictEqual(quadtree().extent([[1, 1], [1, 1]]).extent(), [[1, 1], [2, 2]]); 46 | }); 47 | -------------------------------------------------------------------------------- /test/visit-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.visit(callback) visits each node in a quadtree", () => { 5 | const results = []; 6 | const q = quadtree().addAll([[0, 0], [1, 0], [0, 1], [1, 1]]); 7 | assert.strictEqual(q.visit(function(node, x0, y0, x1, y1) { results.push([x0, y0, x1, y1]); }), q); 8 | assert.deepStrictEqual(results, [ 9 | [0, 0, 2, 2], 10 | [0, 0, 1, 1], 11 | [1, 0, 2, 1], 12 | [0, 1, 1, 2], 13 | [1, 1, 2, 2] 14 | ]); 15 | }); 16 | 17 | it("quadtree.visit(callback) applies pre-order traversal", () => { 18 | const results = []; 19 | const q = quadtree().extent([[0, 0], [960, 960]]).addAll([[100, 100], [200, 200], [300, 300]]); 20 | assert.strictEqual(q.visit(function(node, x0, y0, x1, y1) { results.push([x0, y0, x1, y1]); }), q); 21 | assert.deepStrictEqual(results, [ 22 | [ 0, 0, 1024, 1024], 23 | [ 0, 0, 512, 512], 24 | [ 0, 0, 256, 256], 25 | [ 0, 0, 128, 128], 26 | [128, 128, 256, 256], 27 | [256, 256, 512, 512] 28 | ]); 29 | }); 30 | 31 | it("quadtree.visit(callback) does not recurse if the callback returns truthy", () => { 32 | const results = []; 33 | const q = quadtree().extent([[0, 0], [960, 960]]).addAll([[100, 100], [700, 700], [800, 800]]); 34 | assert.strictEqual(q.visit(function(node, x0, y0, x1, y1) { results.push([x0, y0, x1, y1]); return x0 > 0; }), q); 35 | assert.deepStrictEqual(results, [ 36 | [ 0, 0, 1024, 1024], 37 | [ 0, 0, 512, 512], 38 | [512, 512, 1024, 1024] 39 | ]); 40 | }); 41 | 42 | it("quadtree.visit(callback) on an empty quadtree with no bounds does nothing", () => { 43 | const results = []; 44 | const q = quadtree(); 45 | assert.strictEqual(q.visit(function(node, x0, y0, x1, y1) { results.push([x0, y0, x1, y1]); }), q); 46 | assert.strictEqual(results.length, 0); 47 | }); 48 | 49 | it("quadtree.visit(callback) on an empty quadtree with bounds does nothing", () => { 50 | const results = []; 51 | const q = quadtree().extent([[0, 0], [960, 960]]); 52 | assert.strictEqual(q.visit(function(node, x0, y0, x1, y1) { results.push([x0, y0, x1, y1]); }), q); 53 | assert.deepStrictEqual(results.length, 0); 54 | }); 55 | -------------------------------------------------------------------------------- /src/quadtree.js: -------------------------------------------------------------------------------- 1 | import tree_add, {addAll as tree_addAll} from "./add.js"; 2 | import tree_cover from "./cover.js"; 3 | import tree_data from "./data.js"; 4 | import tree_extent from "./extent.js"; 5 | import tree_find from "./find.js"; 6 | import tree_remove, {removeAll as tree_removeAll} from "./remove.js"; 7 | import tree_root from "./root.js"; 8 | import tree_size from "./size.js"; 9 | import tree_visit from "./visit.js"; 10 | import tree_visitAfter from "./visitAfter.js"; 11 | import tree_x, {defaultX} from "./x.js"; 12 | import tree_y, {defaultY} from "./y.js"; 13 | 14 | export default function quadtree(nodes, x, y) { 15 | var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN); 16 | return nodes == null ? tree : tree.addAll(nodes); 17 | } 18 | 19 | function Quadtree(x, y, x0, y0, x1, y1) { 20 | this._x = x; 21 | this._y = y; 22 | this._x0 = x0; 23 | this._y0 = y0; 24 | this._x1 = x1; 25 | this._y1 = y1; 26 | this._root = undefined; 27 | } 28 | 29 | function leaf_copy(leaf) { 30 | var copy = {data: leaf.data}, next = copy; 31 | while (leaf = leaf.next) next = next.next = {data: leaf.data}; 32 | return copy; 33 | } 34 | 35 | var treeProto = quadtree.prototype = Quadtree.prototype; 36 | 37 | treeProto.copy = function() { 38 | var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), 39 | node = this._root, 40 | nodes, 41 | child; 42 | 43 | if (!node) return copy; 44 | 45 | if (!node.length) return copy._root = leaf_copy(node), copy; 46 | 47 | nodes = [{source: node, target: copy._root = new Array(4)}]; 48 | while (node = nodes.pop()) { 49 | for (var i = 0; i < 4; ++i) { 50 | if (child = node.source[i]) { 51 | if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); 52 | else node.target[i] = leaf_copy(child); 53 | } 54 | } 55 | } 56 | 57 | return copy; 58 | }; 59 | 60 | treeProto.add = tree_add; 61 | treeProto.addAll = tree_addAll; 62 | treeProto.cover = tree_cover; 63 | treeProto.data = tree_data; 64 | treeProto.extent = tree_extent; 65 | treeProto.find = tree_find; 66 | treeProto.remove = tree_remove; 67 | treeProto.removeAll = tree_removeAll; 68 | treeProto.root = tree_root; 69 | treeProto.size = tree_size; 70 | treeProto.visit = tree_visit; 71 | treeProto.visitAfter = tree_visitAfter; 72 | treeProto.x = tree_x; 73 | treeProto.y = tree_y; 74 | -------------------------------------------------------------------------------- /test/addAll-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.addAll(data) creates new points and adds them to the quadtree", () => { 5 | const q = quadtree(); 6 | assert.deepStrictEqual(q.add([0.0, 0.0]).root(), {data: [0, 0]}); 7 | assert.deepStrictEqual(q.add([0.9, 0.9]).root(), [{data: [0, 0]},,, {data: [0.9, 0.9]}]); 8 | assert.deepStrictEqual(q.add([0.9, 0.0]).root(), [{data: [0, 0]}, {data: [0.9, 0]},, {data: [0.9, 0.9]}]); 9 | assert.deepStrictEqual(q.add([0.0, 0.9]).root(), [{data: [0, 0]}, {data: [0.9, 0]}, {data: [0, 0.9]}, {data: [0.9, 0.9]}]); 10 | assert.deepStrictEqual(q.add([0.4, 0.4]).root(), [[{data: [0, 0]},,, {data: [0.4, 0.4]}], {data: [0.9, 0]}, {data: [0, 0.9]}, {data: [0.9, 0.9]}]); 11 | }); 12 | 13 | it("quadtree.addAll(data) ignores points with NaN coordinates", () => { 14 | const q = quadtree(); 15 | assert.deepStrictEqual(q.addAll([[NaN, 0], [0, NaN]]).root(), undefined); 16 | assert.strictEqual(q.extent(), undefined); 17 | assert.deepStrictEqual(q.addAll([[0, 0], [0.9, 0.9]]).root(), [{data: [0, 0]},,, {data: [0.9, 0.9]}]); 18 | assert.deepStrictEqual(q.addAll([[NaN, 0], [0, NaN]]).root(), [{data: [0, 0]},,, {data: [0.9, 0.9]}]); 19 | assert.deepStrictEqual(q.extent(), [[0, 0], [1, 1]]); 20 | }); 21 | 22 | it("quadtree.addAll(data) correctly handles the empty array", () => { 23 | const q = quadtree(); 24 | assert.deepStrictEqual(q.addAll([]).root(), undefined); 25 | assert.strictEqual(q.extent(), undefined); 26 | assert.deepStrictEqual(q.addAll([[0, 0], [1, 1]]).root(), [{data: [0, 0]},,, {data: [1, 1]}]); 27 | assert.deepStrictEqual(q.addAll([]).root(), [{data: [0, 0]},,, {data: [1, 1]}]); 28 | assert.deepStrictEqual(q.extent(), [[0, 0], [2, 2]]); 29 | }); 30 | 31 | it("quadtree.addAll(data) computes the extent of the data before adding", () => { 32 | const q = quadtree().addAll([[0.4, 0.4], [0, 0], [0.9, 0.9]]); 33 | assert.deepStrictEqual(q.root(), [[{data: [0, 0]},,, {data: [0.4, 0.4]}],,, {data: [0.9, 0.9]}]); 34 | }); 35 | 36 | it("quadtree.addAll(iterable) adds points from an iterable", () => { 37 | const q = quadtree().addAll(new Set([[0.4, 0.4], [0, 0], [0.9, 0.9]])); 38 | assert.deepStrictEqual(q.root(), [[{data: [0, 0]},,, {data: [0.4, 0.4]}],,, {data: [0.9, 0.9]}]); 39 | }); 40 | 41 | it("quadtree(iterable) adds points from an iterable", () => { 42 | const q = quadtree(new Set([[0.4, 0.4], [0, 0], [0.9, 0.9]])); 43 | assert.deepStrictEqual(q.root(), [[{data: [0, 0]},,, {data: [0.4, 0.4]}],,, {data: [0.9, 0.9]}]); 44 | }); 45 | -------------------------------------------------------------------------------- /src/add.js: -------------------------------------------------------------------------------- 1 | export default function(d) { 2 | const x = +this._x.call(null, d), 3 | y = +this._y.call(null, d); 4 | return add(this.cover(x, y), x, y, d); 5 | } 6 | 7 | function add(tree, x, y, d) { 8 | if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points 9 | 10 | var parent, 11 | node = tree._root, 12 | leaf = {data: d}, 13 | x0 = tree._x0, 14 | y0 = tree._y0, 15 | x1 = tree._x1, 16 | y1 = tree._y1, 17 | xm, 18 | ym, 19 | xp, 20 | yp, 21 | right, 22 | bottom, 23 | i, 24 | j; 25 | 26 | // If the tree is empty, initialize the root as a leaf. 27 | if (!node) return tree._root = leaf, tree; 28 | 29 | // Find the existing leaf for the new point, or add it. 30 | while (node.length) { 31 | if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; 32 | if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; 33 | if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; 34 | } 35 | 36 | // Is the new point is exactly coincident with the existing point? 37 | xp = +tree._x.call(null, node.data); 38 | yp = +tree._y.call(null, node.data); 39 | if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; 40 | 41 | // Otherwise, split the leaf node until the old and new point are separated. 42 | do { 43 | parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); 44 | if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; 45 | if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; 46 | } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); 47 | return parent[j] = node, parent[i] = leaf, tree; 48 | } 49 | 50 | export function addAll(data) { 51 | if (!Array.isArray(data)) data = Array.from(data); 52 | const n = data.length; 53 | const xz = new Float64Array(n); 54 | const yz = new Float64Array(n); 55 | let x0 = Infinity, y0 = x0, x1 = -x0, y1 = x1; 56 | 57 | // Compute the points and their extent. 58 | for (let i = 0, d, x, y; i < n; ++i) { 59 | if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; 60 | xz[i] = x; 61 | yz[i] = y; 62 | if (x < x0) x0 = x; 63 | if (x > x1) x1 = x; 64 | if (y < y0) y0 = y; 65 | if (y > y1) y1 = y; 66 | } 67 | 68 | // If there were no (valid) points, abort. 69 | if (x0 > x1 || y0 > y1) return this; 70 | 71 | // Expand the tree to cover the new points. 72 | this.cover(x0, y0).cover(x1, y1); 73 | 74 | // Add the new points. 75 | for (let i = 0; i < n; ++i) { 76 | add(this, xz[i], yz[i], data[i]); 77 | } 78 | 79 | return this; 80 | } 81 | -------------------------------------------------------------------------------- /test/add-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.add(datum) creates a new point and adds it to the quadtree", () => { 5 | const q = quadtree(); 6 | assert.deepStrictEqual(q.add([0.0, 0.0]).root(), {data: [0, 0]}); 7 | assert.deepStrictEqual(q.add([0.9, 0.9]).root(), [{data: [0, 0]},,, {data: [0.9, 0.9]}]); 8 | assert.deepStrictEqual(q.add([0.9, 0.0]).root(), [{data: [0, 0]}, {data: [0.9, 0]},, {data: [0.9, 0.9]}]); 9 | assert.deepStrictEqual(q.add([0.0, 0.9]).root(), [{data: [0, 0]}, {data: [0.9, 0]}, {data: [0, 0.9]}, {data: [0.9, 0.9]}]); 10 | assert.deepStrictEqual(q.add([0.4, 0.4]).root(), [[{data: [0, 0]},,, {data: [0.4, 0.4]}], {data: [0.9, 0]}, {data: [0, 0.9]}, {data: [0.9, 0.9]}]); 11 | }); 12 | 13 | it("quadtree.add(datum) handles points being on the perimeter of the quadtree bounds", () => { 14 | const q = quadtree().extent([[0, 0], [1, 1]]); 15 | assert.deepStrictEqual(q.add([0, 0]).root(), {data: [0, 0]}); 16 | assert.deepStrictEqual(q.add([1, 1]).root(), [{data: [0, 0]},,, {data: [1, 1]}]); 17 | assert.deepStrictEqual(q.add([1, 0]).root(), [{data: [0, 0]}, {data: [1, 0]},, {data: [1, 1]}]); 18 | assert.deepStrictEqual(q.add([0, 1]).root(), [{data: [0, 0]}, {data: [1, 0]}, {data: [0, 1]}, {data: [1, 1]}]); 19 | }); 20 | 21 | it("quadtree.add(datum) handles points being to the top of the quadtree bounds", () => { 22 | const q = quadtree().extent([[0, 0], [2, 2]]); 23 | assert.deepStrictEqual(q.add([1, -1]).extent(), [[0, -4], [8, 4]]); 24 | }); 25 | 26 | it("quadtree.add(datum) handles points being to the right of the quadtree bounds", () => { 27 | const q = quadtree().extent([[0, 0], [2, 2]]); 28 | assert.deepStrictEqual(q.add([3, 1]).extent(), [[0, 0], [4, 4]]); 29 | }); 30 | 31 | it("quadtree.add(datum) handles points being to the bottom of the quadtree bounds", () => { 32 | const q = quadtree().extent([[0, 0], [2, 2]]); 33 | assert.deepStrictEqual(q.add([1, 3]).extent(), [[0, 0], [4, 4]]); 34 | }); 35 | 36 | it("quadtree.add(datum) handles points being to the left of the quadtree bounds", () => { 37 | const q = quadtree().extent([[0, 0], [2, 2]]); 38 | assert.deepStrictEqual(q.add([-1, 1]).extent(), [[-4, 0], [4, 8]]); 39 | }); 40 | 41 | it("quadtree.add(datum) handles coincident points by creating a linked list", () => { 42 | const q = quadtree().extent([[0, 0], [1, 1]]); 43 | assert.deepStrictEqual(q.add([0, 0]).root(), {data: [0, 0]}); 44 | assert.deepStrictEqual(q.add([1, 0]).root(), [{data: [0, 0]}, {data: [1, 0]},,, ]); 45 | assert.deepStrictEqual(q.add([0, 1]).root(), [{data: [0, 0]}, {data: [1, 0]}, {data: [0, 1]},, ]); 46 | assert.deepStrictEqual(q.add([0, 1]).root(), [{data: [0, 0]}, {data: [1, 0]}, {data: [0, 1], next: {data: [0, 1]}},, ]); 47 | }); 48 | 49 | it("quadtree.add(datum) implicitly defines trivial bounds for the first point", () => { 50 | const q = quadtree().add([1, 2]); 51 | assert.deepStrictEqual(q.extent(), [[1, 2], [2, 3]]); 52 | assert.deepStrictEqual(q.root(), {data: [1, 2]}); 53 | }); 54 | -------------------------------------------------------------------------------- /test/remove-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.remove(datum) removes a point and returns the quadtree", () => { 5 | const p0 = [1, 1]; 6 | const q = quadtree().add(p0); 7 | assert.deepStrictEqual(q.root(), {data: p0}); 8 | assert.strictEqual(q.remove(p0), q); 9 | assert.deepStrictEqual(q.root(), undefined); 10 | }); 11 | 12 | it("quadtree.remove(datum) removes the only point in the quadtree", () => { 13 | const p0 = [1, 1]; 14 | const q = quadtree().add(p0); 15 | assert.strictEqual(q.remove(p0), q); 16 | assert.deepStrictEqual(q.extent(), [[1, 1], [2, 2]]); 17 | assert.deepStrictEqual(q.root(), undefined); 18 | assert.deepStrictEqual(p0, [1, 1]); 19 | }); 20 | 21 | it("quadtree.remove(datum) removes a first coincident point at the root in the quadtree", () => { 22 | const p0 = [1, 1]; 23 | const p1 = [1, 1]; 24 | const q = quadtree().addAll([p0, p1]); 25 | assert.strictEqual(q.remove(p0), q); 26 | assert.deepStrictEqual(q.extent(), [[1, 1], [2, 2]]); 27 | assert.strictEqual(q.root().data, p1); 28 | assert.deepStrictEqual(p0, [1, 1]); 29 | assert.deepStrictEqual(p1, [1, 1]); 30 | }); 31 | 32 | it("quadtree.remove(datum) removes another coincident point at the root in the quadtree", () => { 33 | const p0 = [1, 1]; 34 | const p1 = [1, 1]; 35 | const q = quadtree().addAll([p0, p1]); 36 | assert.strictEqual(q.remove(p1), q); 37 | assert.deepStrictEqual(q.extent(), [[1, 1], [2, 2]]); 38 | assert.strictEqual(q.root().data, p0); 39 | assert.deepStrictEqual(p0, [1, 1]); 40 | assert.deepStrictEqual(p1, [1, 1]); 41 | }); 42 | 43 | it("quadtree.remove(datum) removes a non-root point in the quadtree", () => { 44 | const p0 = [0, 0]; 45 | const p1 = [1, 1]; 46 | const q = quadtree().addAll([p0, p1]); 47 | assert.strictEqual(q.remove(p0), q); 48 | assert.deepStrictEqual(q.extent(), [[0, 0], [2, 2]]); 49 | assert.strictEqual(q.root().data, p1); 50 | assert.deepStrictEqual(p0, [0, 0]); 51 | assert.deepStrictEqual(p1, [1, 1]); 52 | }); 53 | 54 | it("quadtree.remove(datum) removes another non-root point in the quadtree", () => { 55 | const p0 = [0, 0]; 56 | const p1 = [1, 1]; 57 | const q = quadtree().addAll([p0, p1]); 58 | assert.strictEqual(q.remove(p1), q); 59 | assert.deepStrictEqual(q.extent(), [[0, 0], [2, 2]]); 60 | assert.strictEqual(q.root().data, p0); 61 | assert.deepStrictEqual(p0, [0, 0]); 62 | assert.deepStrictEqual(p1, [1, 1]); 63 | }); 64 | 65 | it("quadtree.remove(datum) ignores a point not in the quadtree", () => { 66 | const p0 = [0, 0]; 67 | const p1 = [1, 1]; 68 | const q0 = quadtree().add(p0); 69 | const q1 = quadtree().add(p1); 70 | assert.strictEqual(q0.remove(p1), q0); 71 | assert.deepStrictEqual(q0.extent(), [[0, 0], [1, 1]]); 72 | assert.strictEqual(q0.root().data, p0); 73 | assert.strictEqual(q1.root().data, p1); 74 | }); 75 | 76 | it("quadtree.remove(datum) ignores a coincident point not in the quadtree", () => { 77 | const p0 = [0, 0]; 78 | const p1 = [0, 0]; 79 | const q0 = quadtree().add(p0); 80 | const q1 = quadtree().add(p1); 81 | assert.strictEqual(q0.remove(p1), q0); 82 | assert.deepStrictEqual(q0.extent(), [[0, 0], [1, 1]]); 83 | assert.strictEqual(q0.root().data, p0); 84 | assert.strictEqual(q1.root().data, p1); 85 | }); 86 | 87 | it("quadtree.remove(datum) removes another point in the quadtree", () => { 88 | const q = quadtree().extent([[0, 0], [959, 959]]); 89 | q.addAll([[630, 438], [715, 464], [523, 519], [646, 318], [434, 620], [570, 489], [520, 345], [459, 443], [346, 405], [529, 444]]); 90 | assert.strictEqual(q.remove(q.find(546, 440)), q); 91 | assert.deepStrictEqual(q.extent(), [[0, 0], [1024, 1024]]); 92 | assert.deepStrictEqual(q.root(), [ 93 | [ 94 | , 95 | , 96 | , 97 | [ 98 | , 99 | , 100 | {data: [346, 405]}, 101 | {data: [459, 443]} 102 | ] 103 | ], 104 | [ 105 | , 106 | , 107 | [ 108 | {data: [520, 345]}, 109 | {data: [646, 318]}, 110 | [ 111 | , 112 | {data: [630, 438]}, 113 | {data: [570, 489]},, 114 | ], 115 | {data: [715, 464]} 116 | ],, 117 | ], 118 | {data: [434, 620]}, 119 | {data: [523, 519]} 120 | ]); 121 | }); 122 | -------------------------------------------------------------------------------- /test/cover-test.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import {quadtree} from "../src/index.js"; 3 | 4 | it("quadtree.cover(x, y) sets a trivial extent if the extent was undefined", () => { 5 | assert.deepStrictEqual(quadtree().cover(1, 2).extent(), [[1, 2], [2, 3]]); 6 | }); 7 | 8 | it("quadtree.cover(x, y) sets a non-trivial squarified and centered extent if the extent was trivial", () => { 9 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(1, 2).extent(), [[0, 0], [4, 4]]); 10 | }); 11 | 12 | it("quadtree.cover(x, y) ignores invalid points", () => { 13 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(NaN, 2).extent(), [[0, 0], [1, 1]]); 14 | }); 15 | 16 | it("quadtree.cover(x, y) repeatedly doubles the existing extent if the extent was non-trivial", () => { 17 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(-1, -1).extent(), [[-4, -4], [4, 4]]); 18 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(1, -1).extent(), [[0, -4], [8, 4]]); 19 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(3, -1).extent(), [[0, -4], [8, 4]]); 20 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(3, 1).extent(), [[0, 0], [4, 4]]); 21 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(3, 3).extent(), [[0, 0], [4, 4]]); 22 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(1, 3).extent(), [[0, 0], [4, 4]]); 23 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(-1, 3).extent(), [[-4, 0], [4, 8]]); 24 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(-1, 1).extent(), [[-4, 0], [4, 8]]); 25 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(-3, -3).extent(), [[-4, -4], [4, 4]]); 26 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(3, -3).extent(), [[0, -4], [8, 4]]); 27 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(5, -3).extent(), [[0, -4], [8, 4]]); 28 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(5, 3).extent(), [[0, 0], [8, 8]]); 29 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(5, 5).extent(), [[0, 0], [8, 8]]); 30 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(3, 5).extent(), [[0, 0], [8, 8]]); 31 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(-3, 5).extent(), [[-4, 0], [4, 8]]); 32 | assert.deepStrictEqual(quadtree().cover(0, 0).cover(2, 2).cover(-3, 3).extent(), [[-4, 0], [4, 8]]); 33 | }); 34 | 35 | it("quadtree.cover(x, y) repeatedly wraps the root node if it has children", () => { 36 | const q = quadtree().add([0, 0]).add([2, 2]); 37 | assert.deepStrictEqual(q.root(), [{data: [0, 0]},,, {data: [2, 2]}]); 38 | assert.deepStrictEqual(q.copy().cover(3, 3).root(), [{data: [0, 0]},,, {data: [2, 2]}]); 39 | assert.deepStrictEqual(q.copy().cover(-1, 3).root(), [,[{data: [0, 0]},,, {data: [2, 2]}],,, ]); 40 | assert.deepStrictEqual(q.copy().cover(3, -1).root(), [,, [{data: [0, 0]},,, {data: [2, 2]}],, ]); 41 | assert.deepStrictEqual(q.copy().cover(-1, -1).root(), [,,, [{data: [0, 0]},,, {data: [2, 2]}]]); 42 | assert.deepStrictEqual(q.copy().cover(5, 5).root(), [[{data: [0, 0]},,, {data: [2, 2]}],,,, ]); 43 | assert.deepStrictEqual(q.copy().cover(-3, 5).root(), [,[{data: [0, 0]},,, {data: [2, 2]}],,, ]); 44 | assert.deepStrictEqual(q.copy().cover(5, -3).root(), [,, [{data: [0, 0]},,, {data: [2, 2]}],, ]); 45 | assert.deepStrictEqual(q.copy().cover(-3, -3).root(), [,,, [{data: [0, 0]},,, {data: [2, 2]}]]); 46 | }); 47 | 48 | it("quadtree.cover(x, y) does not wrap the root node if it is a leaf", () => { 49 | const q = quadtree().cover(0, 0).add([2, 2]); 50 | assert.deepStrictEqual(q.root(), {data: [2, 2]}); 51 | assert.deepStrictEqual(q.copy().cover(3, 3).root(), {data: [2, 2]}); 52 | assert.deepStrictEqual(q.copy().cover(-1, 3).root(), {data: [2, 2]}); 53 | assert.deepStrictEqual(q.copy().cover(3, -1).root(), {data: [2, 2]}); 54 | assert.deepStrictEqual(q.copy().cover(-1, -1).root(), {data: [2, 2]}); 55 | assert.deepStrictEqual(q.copy().cover(5, 5).root(), {data: [2, 2]}); 56 | assert.deepStrictEqual(q.copy().cover(-3, 5).root(), {data: [2, 2]}); 57 | assert.deepStrictEqual(q.copy().cover(5, -3).root(), {data: [2, 2]}); 58 | assert.deepStrictEqual(q.copy().cover(-3, -3).root(), {data: [2, 2]}); 59 | }); 60 | 61 | it("quadtree.cover(x, y) does not wrap the root node if it is undefined", () => { 62 | const q = quadtree().cover(0, 0).cover(2, 2); 63 | assert.strictEqual(q.root(), undefined); 64 | assert.strictEqual(q.copy().cover(3, 3).root(), undefined); 65 | assert.strictEqual(q.copy().cover(-1, 3).root(), undefined); 66 | assert.strictEqual(q.copy().cover(3, -1).root(), undefined); 67 | assert.strictEqual(q.copy().cover(-1, -1).root(), undefined); 68 | assert.strictEqual(q.copy().cover(5, 5).root(), undefined); 69 | assert.strictEqual(q.copy().cover(-3, 5).root(), undefined); 70 | assert.strictEqual(q.copy().cover(5, -3).root(), undefined); 71 | assert.strictEqual(q.copy().cover(-3, -3).root(), undefined); 72 | }); 73 | 74 | it("quadtree.cover() does not crash on huge values", () => { 75 | quadtree([[1e23, 0]]); 76 | }); 77 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@7.12.11": 6 | version "7.12.11" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" 8 | integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== 9 | dependencies: 10 | "@babel/highlight" "^7.10.4" 11 | 12 | "@babel/code-frame@^7.10.4": 13 | version "7.12.13" 14 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" 15 | integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== 16 | dependencies: 17 | "@babel/highlight" "^7.12.13" 18 | 19 | "@babel/helper-validator-identifier@^7.14.0": 20 | version "7.14.0" 21 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" 22 | integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== 23 | 24 | "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": 25 | version "7.14.0" 26 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" 27 | integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== 28 | dependencies: 29 | "@babel/helper-validator-identifier" "^7.14.0" 30 | chalk "^2.0.0" 31 | js-tokens "^4.0.0" 32 | 33 | "@eslint/eslintrc@^0.4.2": 34 | version "0.4.2" 35 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" 36 | integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg== 37 | dependencies: 38 | ajv "^6.12.4" 39 | debug "^4.1.1" 40 | espree "^7.3.0" 41 | globals "^13.9.0" 42 | ignore "^4.0.6" 43 | import-fresh "^3.2.1" 44 | js-yaml "^3.13.1" 45 | minimatch "^3.0.4" 46 | strip-json-comments "^3.1.1" 47 | 48 | "@types/node@*": 49 | version "15.12.1" 50 | resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.1.tgz#9b60797dee1895383a725f828a869c86c6caa5c2" 51 | integrity sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw== 52 | 53 | "@ungap/promise-all-settled@1.1.2": 54 | version "1.1.2" 55 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 56 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 57 | 58 | acorn-jsx@^5.3.1: 59 | version "5.3.1" 60 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" 61 | integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== 62 | 63 | acorn@^7.4.0: 64 | version "7.4.1" 65 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" 66 | integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 67 | 68 | ajv@^6.10.0, ajv@^6.12.4: 69 | version "6.12.6" 70 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 71 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 72 | dependencies: 73 | fast-deep-equal "^3.1.1" 74 | fast-json-stable-stringify "^2.0.0" 75 | json-schema-traverse "^0.4.1" 76 | uri-js "^4.2.2" 77 | 78 | ajv@^8.0.1: 79 | version "8.5.0" 80 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" 81 | integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== 82 | dependencies: 83 | fast-deep-equal "^3.1.1" 84 | json-schema-traverse "^1.0.0" 85 | require-from-string "^2.0.2" 86 | uri-js "^4.2.2" 87 | 88 | ansi-colors@4.1.1, ansi-colors@^4.1.1: 89 | version "4.1.1" 90 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 91 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 92 | 93 | ansi-regex@^3.0.0: 94 | version "3.0.0" 95 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 96 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 97 | 98 | ansi-regex@^5.0.0: 99 | version "5.0.0" 100 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" 101 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 102 | 103 | ansi-styles@^3.2.1: 104 | version "3.2.1" 105 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 106 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 107 | dependencies: 108 | color-convert "^1.9.0" 109 | 110 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 111 | version "4.3.0" 112 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 113 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 114 | dependencies: 115 | color-convert "^2.0.1" 116 | 117 | anymatch@~3.1.1: 118 | version "3.1.2" 119 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 120 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 121 | dependencies: 122 | normalize-path "^3.0.0" 123 | picomatch "^2.0.4" 124 | 125 | argparse@^1.0.7: 126 | version "1.0.10" 127 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 128 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 129 | dependencies: 130 | sprintf-js "~1.0.2" 131 | 132 | argparse@^2.0.1: 133 | version "2.0.1" 134 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 135 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 136 | 137 | astral-regex@^2.0.0: 138 | version "2.0.0" 139 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" 140 | integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== 141 | 142 | balanced-match@^1.0.0: 143 | version "1.0.2" 144 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 145 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 146 | 147 | binary-extensions@^2.0.0: 148 | version "2.2.0" 149 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 150 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 151 | 152 | brace-expansion@^1.1.7: 153 | version "1.1.11" 154 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 155 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 156 | dependencies: 157 | balanced-match "^1.0.0" 158 | concat-map "0.0.1" 159 | 160 | braces@~3.0.2: 161 | version "3.0.2" 162 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 163 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 164 | dependencies: 165 | fill-range "^7.0.1" 166 | 167 | browser-stdout@1.3.1: 168 | version "1.3.1" 169 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 170 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 171 | 172 | buffer-from@^1.0.0: 173 | version "1.1.1" 174 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 175 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 176 | 177 | callsites@^3.0.0: 178 | version "3.1.0" 179 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 180 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 181 | 182 | camelcase@^6.0.0: 183 | version "6.2.0" 184 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" 185 | integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== 186 | 187 | chalk@^2.0.0: 188 | version "2.4.2" 189 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 190 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 191 | dependencies: 192 | ansi-styles "^3.2.1" 193 | escape-string-regexp "^1.0.5" 194 | supports-color "^5.3.0" 195 | 196 | chalk@^4.0.0: 197 | version "4.1.1" 198 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" 199 | integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== 200 | dependencies: 201 | ansi-styles "^4.1.0" 202 | supports-color "^7.1.0" 203 | 204 | chokidar@3.5.1: 205 | version "3.5.1" 206 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" 207 | integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== 208 | dependencies: 209 | anymatch "~3.1.1" 210 | braces "~3.0.2" 211 | glob-parent "~5.1.0" 212 | is-binary-path "~2.1.0" 213 | is-glob "~4.0.1" 214 | normalize-path "~3.0.0" 215 | readdirp "~3.5.0" 216 | optionalDependencies: 217 | fsevents "~2.3.1" 218 | 219 | cliui@^7.0.2: 220 | version "7.0.4" 221 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 222 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 223 | dependencies: 224 | string-width "^4.2.0" 225 | strip-ansi "^6.0.0" 226 | wrap-ansi "^7.0.0" 227 | 228 | color-convert@^1.9.0: 229 | version "1.9.3" 230 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 231 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 232 | dependencies: 233 | color-name "1.1.3" 234 | 235 | color-convert@^2.0.1: 236 | version "2.0.1" 237 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 238 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 239 | dependencies: 240 | color-name "~1.1.4" 241 | 242 | color-name@1.1.3: 243 | version "1.1.3" 244 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 245 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 246 | 247 | color-name@~1.1.4: 248 | version "1.1.4" 249 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 250 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 251 | 252 | commander@^2.20.0: 253 | version "2.20.3" 254 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 255 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 256 | 257 | concat-map@0.0.1: 258 | version "0.0.1" 259 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 260 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 261 | 262 | cross-spawn@^7.0.2: 263 | version "7.0.3" 264 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 265 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 266 | dependencies: 267 | path-key "^3.1.0" 268 | shebang-command "^2.0.0" 269 | which "^2.0.1" 270 | 271 | "d3-array@1 - 2": 272 | version "2.12.1" 273 | resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" 274 | integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== 275 | dependencies: 276 | internmap "^1.0.0" 277 | 278 | debug@4.3.1, debug@^4.0.1, debug@^4.1.1: 279 | version "4.3.1" 280 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" 281 | integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== 282 | dependencies: 283 | ms "2.1.2" 284 | 285 | decamelize@^4.0.0: 286 | version "4.0.0" 287 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 288 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 289 | 290 | deep-is@^0.1.3: 291 | version "0.1.3" 292 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 293 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 294 | 295 | diff@5.0.0: 296 | version "5.0.0" 297 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 298 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 299 | 300 | doctrine@^3.0.0: 301 | version "3.0.0" 302 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 303 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 304 | dependencies: 305 | esutils "^2.0.2" 306 | 307 | emoji-regex@^8.0.0: 308 | version "8.0.0" 309 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 310 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 311 | 312 | enquirer@^2.3.5: 313 | version "2.3.6" 314 | resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" 315 | integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== 316 | dependencies: 317 | ansi-colors "^4.1.1" 318 | 319 | escalade@^3.1.1: 320 | version "3.1.1" 321 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 322 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 323 | 324 | escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: 325 | version "4.0.0" 326 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 327 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 328 | 329 | escape-string-regexp@^1.0.5: 330 | version "1.0.5" 331 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 332 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 333 | 334 | eslint-scope@^5.1.1: 335 | version "5.1.1" 336 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" 337 | integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== 338 | dependencies: 339 | esrecurse "^4.3.0" 340 | estraverse "^4.1.1" 341 | 342 | eslint-utils@^2.1.0: 343 | version "2.1.0" 344 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" 345 | integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== 346 | dependencies: 347 | eslint-visitor-keys "^1.1.0" 348 | 349 | eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: 350 | version "1.3.0" 351 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" 352 | integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== 353 | 354 | eslint-visitor-keys@^2.0.0: 355 | version "2.1.0" 356 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" 357 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 358 | 359 | eslint@7: 360 | version "7.28.0" 361 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.28.0.tgz#435aa17a0b82c13bb2be9d51408b617e49c1e820" 362 | integrity sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== 363 | dependencies: 364 | "@babel/code-frame" "7.12.11" 365 | "@eslint/eslintrc" "^0.4.2" 366 | ajv "^6.10.0" 367 | chalk "^4.0.0" 368 | cross-spawn "^7.0.2" 369 | debug "^4.0.1" 370 | doctrine "^3.0.0" 371 | enquirer "^2.3.5" 372 | escape-string-regexp "^4.0.0" 373 | eslint-scope "^5.1.1" 374 | eslint-utils "^2.1.0" 375 | eslint-visitor-keys "^2.0.0" 376 | espree "^7.3.1" 377 | esquery "^1.4.0" 378 | esutils "^2.0.2" 379 | fast-deep-equal "^3.1.3" 380 | file-entry-cache "^6.0.1" 381 | functional-red-black-tree "^1.0.1" 382 | glob-parent "^5.1.2" 383 | globals "^13.6.0" 384 | ignore "^4.0.6" 385 | import-fresh "^3.0.0" 386 | imurmurhash "^0.1.4" 387 | is-glob "^4.0.0" 388 | js-yaml "^3.13.1" 389 | json-stable-stringify-without-jsonify "^1.0.1" 390 | levn "^0.4.1" 391 | lodash.merge "^4.6.2" 392 | minimatch "^3.0.4" 393 | natural-compare "^1.4.0" 394 | optionator "^0.9.1" 395 | progress "^2.0.0" 396 | regexpp "^3.1.0" 397 | semver "^7.2.1" 398 | strip-ansi "^6.0.0" 399 | strip-json-comments "^3.1.0" 400 | table "^6.0.9" 401 | text-table "^0.2.0" 402 | v8-compile-cache "^2.0.3" 403 | 404 | espree@^7.3.0, espree@^7.3.1: 405 | version "7.3.1" 406 | resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" 407 | integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== 408 | dependencies: 409 | acorn "^7.4.0" 410 | acorn-jsx "^5.3.1" 411 | eslint-visitor-keys "^1.3.0" 412 | 413 | esprima@^4.0.0: 414 | version "4.0.1" 415 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 416 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 417 | 418 | esquery@^1.4.0: 419 | version "1.4.0" 420 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" 421 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 422 | dependencies: 423 | estraverse "^5.1.0" 424 | 425 | esrecurse@^4.3.0: 426 | version "4.3.0" 427 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 428 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 429 | dependencies: 430 | estraverse "^5.2.0" 431 | 432 | estraverse@^4.1.1: 433 | version "4.3.0" 434 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 435 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 436 | 437 | estraverse@^5.1.0, estraverse@^5.2.0: 438 | version "5.2.0" 439 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" 440 | integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== 441 | 442 | esutils@^2.0.2: 443 | version "2.0.3" 444 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 445 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 446 | 447 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 448 | version "3.1.3" 449 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 450 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 451 | 452 | fast-json-stable-stringify@^2.0.0: 453 | version "2.1.0" 454 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 455 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 456 | 457 | fast-levenshtein@^2.0.6: 458 | version "2.0.6" 459 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 460 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 461 | 462 | file-entry-cache@^6.0.1: 463 | version "6.0.1" 464 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 465 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 466 | dependencies: 467 | flat-cache "^3.0.4" 468 | 469 | fill-range@^7.0.1: 470 | version "7.0.1" 471 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 472 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 473 | dependencies: 474 | to-regex-range "^5.0.1" 475 | 476 | find-up@5.0.0: 477 | version "5.0.0" 478 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 479 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 480 | dependencies: 481 | locate-path "^6.0.0" 482 | path-exists "^4.0.0" 483 | 484 | flat-cache@^3.0.4: 485 | version "3.0.4" 486 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" 487 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 488 | dependencies: 489 | flatted "^3.1.0" 490 | rimraf "^3.0.2" 491 | 492 | flat@^5.0.2: 493 | version "5.0.2" 494 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 495 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 496 | 497 | flatted@^3.1.0: 498 | version "3.1.1" 499 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" 500 | integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== 501 | 502 | fs.realpath@^1.0.0: 503 | version "1.0.0" 504 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 505 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 506 | 507 | fsevents@~2.3.1: 508 | version "2.3.2" 509 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 510 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 511 | 512 | functional-red-black-tree@^1.0.1: 513 | version "1.0.1" 514 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 515 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 516 | 517 | get-caller-file@^2.0.5: 518 | version "2.0.5" 519 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 520 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 521 | 522 | glob-parent@^5.1.2, glob-parent@~5.1.0: 523 | version "5.1.2" 524 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 525 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 526 | dependencies: 527 | is-glob "^4.0.1" 528 | 529 | glob@7.1.6: 530 | version "7.1.6" 531 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 532 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 533 | dependencies: 534 | fs.realpath "^1.0.0" 535 | inflight "^1.0.4" 536 | inherits "2" 537 | minimatch "^3.0.4" 538 | once "^1.3.0" 539 | path-is-absolute "^1.0.0" 540 | 541 | glob@^7.1.3: 542 | version "7.1.7" 543 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" 544 | integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== 545 | dependencies: 546 | fs.realpath "^1.0.0" 547 | inflight "^1.0.4" 548 | inherits "2" 549 | minimatch "^3.0.4" 550 | once "^1.3.0" 551 | path-is-absolute "^1.0.0" 552 | 553 | globals@^13.6.0, globals@^13.9.0: 554 | version "13.9.0" 555 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" 556 | integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== 557 | dependencies: 558 | type-fest "^0.20.2" 559 | 560 | growl@1.10.5: 561 | version "1.10.5" 562 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 563 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 564 | 565 | has-flag@^3.0.0: 566 | version "3.0.0" 567 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 568 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 569 | 570 | has-flag@^4.0.0: 571 | version "4.0.0" 572 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 573 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 574 | 575 | he@1.2.0: 576 | version "1.2.0" 577 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 578 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 579 | 580 | ignore@^4.0.6: 581 | version "4.0.6" 582 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" 583 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== 584 | 585 | import-fresh@^3.0.0, import-fresh@^3.2.1: 586 | version "3.3.0" 587 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 588 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 589 | dependencies: 590 | parent-module "^1.0.0" 591 | resolve-from "^4.0.0" 592 | 593 | imurmurhash@^0.1.4: 594 | version "0.1.4" 595 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 596 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 597 | 598 | inflight@^1.0.4: 599 | version "1.0.6" 600 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 601 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 602 | dependencies: 603 | once "^1.3.0" 604 | wrappy "1" 605 | 606 | inherits@2: 607 | version "2.0.4" 608 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 609 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 610 | 611 | internmap@^1.0.0: 612 | version "1.0.1" 613 | resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" 614 | integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== 615 | 616 | is-binary-path@~2.1.0: 617 | version "2.1.0" 618 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 619 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 620 | dependencies: 621 | binary-extensions "^2.0.0" 622 | 623 | is-extglob@^2.1.1: 624 | version "2.1.1" 625 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 626 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 627 | 628 | is-fullwidth-code-point@^2.0.0: 629 | version "2.0.0" 630 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 631 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 632 | 633 | is-fullwidth-code-point@^3.0.0: 634 | version "3.0.0" 635 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 636 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 637 | 638 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: 639 | version "4.0.1" 640 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 641 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 642 | dependencies: 643 | is-extglob "^2.1.1" 644 | 645 | is-number@^7.0.0: 646 | version "7.0.0" 647 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 648 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 649 | 650 | is-plain-obj@^2.1.0: 651 | version "2.1.0" 652 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 653 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 654 | 655 | isexe@^2.0.0: 656 | version "2.0.0" 657 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 658 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 659 | 660 | jest-worker@^26.2.1: 661 | version "26.6.2" 662 | resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" 663 | integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== 664 | dependencies: 665 | "@types/node" "*" 666 | merge-stream "^2.0.0" 667 | supports-color "^7.0.0" 668 | 669 | js-tokens@^4.0.0: 670 | version "4.0.0" 671 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 672 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 673 | 674 | js-yaml@4.0.0: 675 | version "4.0.0" 676 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" 677 | integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== 678 | dependencies: 679 | argparse "^2.0.1" 680 | 681 | js-yaml@^3.13.1: 682 | version "3.14.1" 683 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 684 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 685 | dependencies: 686 | argparse "^1.0.7" 687 | esprima "^4.0.0" 688 | 689 | json-schema-traverse@^0.4.1: 690 | version "0.4.1" 691 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 692 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 693 | 694 | json-schema-traverse@^1.0.0: 695 | version "1.0.0" 696 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" 697 | integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== 698 | 699 | json-stable-stringify-without-jsonify@^1.0.1: 700 | version "1.0.1" 701 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 702 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 703 | 704 | levn@^0.4.1: 705 | version "0.4.1" 706 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 707 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 708 | dependencies: 709 | prelude-ls "^1.2.1" 710 | type-check "~0.4.0" 711 | 712 | locate-path@^6.0.0: 713 | version "6.0.0" 714 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 715 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 716 | dependencies: 717 | p-locate "^5.0.0" 718 | 719 | lodash.clonedeep@^4.5.0: 720 | version "4.5.0" 721 | resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" 722 | integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= 723 | 724 | lodash.merge@^4.6.2: 725 | version "4.6.2" 726 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 727 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 728 | 729 | lodash.truncate@^4.4.2: 730 | version "4.4.2" 731 | resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" 732 | integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= 733 | 734 | log-symbols@4.0.0: 735 | version "4.0.0" 736 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" 737 | integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== 738 | dependencies: 739 | chalk "^4.0.0" 740 | 741 | lru-cache@^6.0.0: 742 | version "6.0.0" 743 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 744 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 745 | dependencies: 746 | yallist "^4.0.0" 747 | 748 | merge-stream@^2.0.0: 749 | version "2.0.0" 750 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 751 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 752 | 753 | minimatch@3.0.4, minimatch@^3.0.4: 754 | version "3.0.4" 755 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 756 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 757 | dependencies: 758 | brace-expansion "^1.1.7" 759 | 760 | mocha@8: 761 | version "8.4.0" 762 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.4.0.tgz#677be88bf15980a3cae03a73e10a0fc3997f0cff" 763 | integrity sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ== 764 | dependencies: 765 | "@ungap/promise-all-settled" "1.1.2" 766 | ansi-colors "4.1.1" 767 | browser-stdout "1.3.1" 768 | chokidar "3.5.1" 769 | debug "4.3.1" 770 | diff "5.0.0" 771 | escape-string-regexp "4.0.0" 772 | find-up "5.0.0" 773 | glob "7.1.6" 774 | growl "1.10.5" 775 | he "1.2.0" 776 | js-yaml "4.0.0" 777 | log-symbols "4.0.0" 778 | minimatch "3.0.4" 779 | ms "2.1.3" 780 | nanoid "3.1.20" 781 | serialize-javascript "5.0.1" 782 | strip-json-comments "3.1.1" 783 | supports-color "8.1.1" 784 | which "2.0.2" 785 | wide-align "1.1.3" 786 | workerpool "6.1.0" 787 | yargs "16.2.0" 788 | yargs-parser "20.2.4" 789 | yargs-unparser "2.0.0" 790 | 791 | ms@2.1.2: 792 | version "2.1.2" 793 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 794 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 795 | 796 | ms@2.1.3: 797 | version "2.1.3" 798 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 799 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 800 | 801 | nanoid@3.1.20: 802 | version "3.1.20" 803 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" 804 | integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== 805 | 806 | natural-compare@^1.4.0: 807 | version "1.4.0" 808 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 809 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 810 | 811 | normalize-path@^3.0.0, normalize-path@~3.0.0: 812 | version "3.0.0" 813 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 814 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 815 | 816 | once@^1.3.0: 817 | version "1.4.0" 818 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 819 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 820 | dependencies: 821 | wrappy "1" 822 | 823 | optionator@^0.9.1: 824 | version "0.9.1" 825 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" 826 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 827 | dependencies: 828 | deep-is "^0.1.3" 829 | fast-levenshtein "^2.0.6" 830 | levn "^0.4.1" 831 | prelude-ls "^1.2.1" 832 | type-check "^0.4.0" 833 | word-wrap "^1.2.3" 834 | 835 | p-limit@^3.0.2: 836 | version "3.1.0" 837 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 838 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 839 | dependencies: 840 | yocto-queue "^0.1.0" 841 | 842 | p-locate@^5.0.0: 843 | version "5.0.0" 844 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 845 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 846 | dependencies: 847 | p-limit "^3.0.2" 848 | 849 | parent-module@^1.0.0: 850 | version "1.0.1" 851 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 852 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 853 | dependencies: 854 | callsites "^3.0.0" 855 | 856 | path-exists@^4.0.0: 857 | version "4.0.0" 858 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 859 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 860 | 861 | path-is-absolute@^1.0.0: 862 | version "1.0.1" 863 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 864 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 865 | 866 | path-key@^3.1.0: 867 | version "3.1.1" 868 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 869 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 870 | 871 | picomatch@^2.0.4, picomatch@^2.2.1: 872 | version "2.3.0" 873 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" 874 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== 875 | 876 | prelude-ls@^1.2.1: 877 | version "1.2.1" 878 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 879 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 880 | 881 | progress@^2.0.0: 882 | version "2.0.3" 883 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 884 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 885 | 886 | punycode@^2.1.0: 887 | version "2.1.1" 888 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 889 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 890 | 891 | randombytes@^2.1.0: 892 | version "2.1.0" 893 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 894 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 895 | dependencies: 896 | safe-buffer "^5.1.0" 897 | 898 | readdirp@~3.5.0: 899 | version "3.5.0" 900 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" 901 | integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== 902 | dependencies: 903 | picomatch "^2.2.1" 904 | 905 | regexpp@^3.1.0: 906 | version "3.1.0" 907 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" 908 | integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== 909 | 910 | require-directory@^2.1.1: 911 | version "2.1.1" 912 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 913 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 914 | 915 | require-from-string@^2.0.2: 916 | version "2.0.2" 917 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" 918 | integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== 919 | 920 | resolve-from@^4.0.0: 921 | version "4.0.0" 922 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 923 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 924 | 925 | rimraf@^3.0.2: 926 | version "3.0.2" 927 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 928 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 929 | dependencies: 930 | glob "^7.1.3" 931 | 932 | rollup-plugin-terser@7: 933 | version "7.0.2" 934 | resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" 935 | integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== 936 | dependencies: 937 | "@babel/code-frame" "^7.10.4" 938 | jest-worker "^26.2.1" 939 | serialize-javascript "^4.0.0" 940 | terser "^5.0.0" 941 | 942 | rollup@2: 943 | version "2.50.6" 944 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.50.6.tgz#24e2211caf9031081656e98a5e5e94d3b5e786e2" 945 | integrity sha512-6c5CJPLVgo0iNaZWWliNu1Kl43tjP9LZcp6D/tkf2eLH2a9/WeHxg9vfTFl8QV/2SOyaJX37CEm9XuGM0rviUg== 946 | optionalDependencies: 947 | fsevents "~2.3.1" 948 | 949 | safe-buffer@^5.1.0: 950 | version "5.2.1" 951 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 952 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 953 | 954 | semver@^7.2.1: 955 | version "7.3.5" 956 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" 957 | integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== 958 | dependencies: 959 | lru-cache "^6.0.0" 960 | 961 | serialize-javascript@5.0.1: 962 | version "5.0.1" 963 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" 964 | integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== 965 | dependencies: 966 | randombytes "^2.1.0" 967 | 968 | serialize-javascript@^4.0.0: 969 | version "4.0.0" 970 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" 971 | integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== 972 | dependencies: 973 | randombytes "^2.1.0" 974 | 975 | shebang-command@^2.0.0: 976 | version "2.0.0" 977 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 978 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 979 | dependencies: 980 | shebang-regex "^3.0.0" 981 | 982 | shebang-regex@^3.0.0: 983 | version "3.0.0" 984 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 985 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 986 | 987 | slice-ansi@^4.0.0: 988 | version "4.0.0" 989 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" 990 | integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== 991 | dependencies: 992 | ansi-styles "^4.0.0" 993 | astral-regex "^2.0.0" 994 | is-fullwidth-code-point "^3.0.0" 995 | 996 | source-map-support@~0.5.19: 997 | version "0.5.19" 998 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" 999 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== 1000 | dependencies: 1001 | buffer-from "^1.0.0" 1002 | source-map "^0.6.0" 1003 | 1004 | source-map@^0.6.0: 1005 | version "0.6.1" 1006 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1007 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1008 | 1009 | source-map@~0.7.2: 1010 | version "0.7.3" 1011 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" 1012 | integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== 1013 | 1014 | sprintf-js@~1.0.2: 1015 | version "1.0.3" 1016 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1017 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 1018 | 1019 | "string-width@^1.0.2 || 2": 1020 | version "2.1.1" 1021 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 1022 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 1023 | dependencies: 1024 | is-fullwidth-code-point "^2.0.0" 1025 | strip-ansi "^4.0.0" 1026 | 1027 | string-width@^4.1.0, string-width@^4.2.0: 1028 | version "4.2.2" 1029 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" 1030 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== 1031 | dependencies: 1032 | emoji-regex "^8.0.0" 1033 | is-fullwidth-code-point "^3.0.0" 1034 | strip-ansi "^6.0.0" 1035 | 1036 | strip-ansi@^4.0.0: 1037 | version "4.0.0" 1038 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 1039 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 1040 | dependencies: 1041 | ansi-regex "^3.0.0" 1042 | 1043 | strip-ansi@^6.0.0: 1044 | version "6.0.0" 1045 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" 1046 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 1047 | dependencies: 1048 | ansi-regex "^5.0.0" 1049 | 1050 | strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: 1051 | version "3.1.1" 1052 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1053 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1054 | 1055 | supports-color@8.1.1: 1056 | version "8.1.1" 1057 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1058 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1059 | dependencies: 1060 | has-flag "^4.0.0" 1061 | 1062 | supports-color@^5.3.0: 1063 | version "5.5.0" 1064 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1065 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1066 | dependencies: 1067 | has-flag "^3.0.0" 1068 | 1069 | supports-color@^7.0.0, supports-color@^7.1.0: 1070 | version "7.2.0" 1071 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1072 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1073 | dependencies: 1074 | has-flag "^4.0.0" 1075 | 1076 | table@^6.0.9: 1077 | version "6.7.1" 1078 | resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" 1079 | integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== 1080 | dependencies: 1081 | ajv "^8.0.1" 1082 | lodash.clonedeep "^4.5.0" 1083 | lodash.truncate "^4.4.2" 1084 | slice-ansi "^4.0.0" 1085 | string-width "^4.2.0" 1086 | strip-ansi "^6.0.0" 1087 | 1088 | terser@^5.0.0: 1089 | version "5.7.0" 1090 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" 1091 | integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== 1092 | dependencies: 1093 | commander "^2.20.0" 1094 | source-map "~0.7.2" 1095 | source-map-support "~0.5.19" 1096 | 1097 | text-table@^0.2.0: 1098 | version "0.2.0" 1099 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1100 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1101 | 1102 | to-regex-range@^5.0.1: 1103 | version "5.0.1" 1104 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1105 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1106 | dependencies: 1107 | is-number "^7.0.0" 1108 | 1109 | type-check@^0.4.0, type-check@~0.4.0: 1110 | version "0.4.0" 1111 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 1112 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1113 | dependencies: 1114 | prelude-ls "^1.2.1" 1115 | 1116 | type-fest@^0.20.2: 1117 | version "0.20.2" 1118 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1119 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1120 | 1121 | uri-js@^4.2.2: 1122 | version "4.4.1" 1123 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1124 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1125 | dependencies: 1126 | punycode "^2.1.0" 1127 | 1128 | v8-compile-cache@^2.0.3: 1129 | version "2.3.0" 1130 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 1131 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 1132 | 1133 | which@2.0.2, which@^2.0.1: 1134 | version "2.0.2" 1135 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1136 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1137 | dependencies: 1138 | isexe "^2.0.0" 1139 | 1140 | wide-align@1.1.3: 1141 | version "1.1.3" 1142 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 1143 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 1144 | dependencies: 1145 | string-width "^1.0.2 || 2" 1146 | 1147 | word-wrap@^1.2.3: 1148 | version "1.2.3" 1149 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 1150 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1151 | 1152 | workerpool@6.1.0: 1153 | version "6.1.0" 1154 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" 1155 | integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== 1156 | 1157 | wrap-ansi@^7.0.0: 1158 | version "7.0.0" 1159 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1160 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1161 | dependencies: 1162 | ansi-styles "^4.0.0" 1163 | string-width "^4.1.0" 1164 | strip-ansi "^6.0.0" 1165 | 1166 | wrappy@1: 1167 | version "1.0.2" 1168 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1169 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1170 | 1171 | y18n@^5.0.5: 1172 | version "5.0.8" 1173 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1174 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1175 | 1176 | yallist@^4.0.0: 1177 | version "4.0.0" 1178 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1179 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1180 | 1181 | yargs-parser@20.2.4: 1182 | version "20.2.4" 1183 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1184 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1185 | 1186 | yargs-parser@^20.2.2: 1187 | version "20.2.7" 1188 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" 1189 | integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== 1190 | 1191 | yargs-unparser@2.0.0: 1192 | version "2.0.0" 1193 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 1194 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1195 | dependencies: 1196 | camelcase "^6.0.0" 1197 | decamelize "^4.0.0" 1198 | flat "^5.0.2" 1199 | is-plain-obj "^2.1.0" 1200 | 1201 | yargs@16.2.0: 1202 | version "16.2.0" 1203 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1204 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1205 | dependencies: 1206 | cliui "^7.0.2" 1207 | escalade "^3.1.1" 1208 | get-caller-file "^2.0.5" 1209 | require-directory "^2.1.1" 1210 | string-width "^4.2.0" 1211 | y18n "^5.0.5" 1212 | yargs-parser "^20.2.2" 1213 | 1214 | yocto-queue@^0.1.0: 1215 | version "0.1.0" 1216 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1217 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1218 | --------------------------------------------------------------------------------