├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── dist └── index.js ├── fakes └── generate-tree-default.js ├── package-lock.json ├── package.json ├── src ├── node.js └── tree.js ├── test ├── node-test.js └── tree-test.js ├── utils ├── node-compare-by-id.js ├── remove-empty-children.js ├── search-node.js ├── serialize-tree.js ├── show-tree.js └── traversal-tree.js └── yarn.lock /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [12.x, 14.x, 16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: 'npm' 29 | - run: yarn install 30 | - run: yarn test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /tmp 3 | /node_modules 4 | /bower_components 5 | /.sass-cache 6 | /connect.lock 7 | /coverage/* 8 | /libpeerconnection.log 9 | npm-debug.log 10 | testem.log 11 | demo/ 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "favorites.sortDirection": "ASC", 3 | "favorites.groupsFirst": true 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Denis Ivanov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iron-tree 2 | This package builds a tree and gives a lot of useful methods for managing a tree and its nodes 3 | 4 | # Install 5 | `npm install @denq/iron-tree --save` 6 | 7 | # Base usage 8 | 9 | ```js 10 | // create tree 11 | const object = { id: 1, title: 'Root' }; 12 | const tree = new Tree(object); 13 | 14 | // add nodes 15 | const regularObject = { id:2, title: 'Node 2'} 16 | tree.add((parentNode) => { 17 | return parentNode.get('id') === 1; 18 | }, regularObject); 19 | 20 | // contains node 21 | const targetNode = tree.contains((currentNode) => { 22 | return currentNode.get('id') === 2; 23 | }); 24 | 25 | // remove node 26 | const result = tree.remove((currentNode) => { 27 | return currentNode.get('id') === 2; 28 | }); 29 | 30 | // traversal 31 | const criteria = (currentNode) => currentNode.get('id') === 1; 32 | tree.traversal(criteria, (currentNode) => { 33 | currentNode.set('some', true); 34 | }); 35 | 36 | // getPath 37 | const criteria = (currentNode) => currentNode.get('id') === 6; 38 | const targetNode = tree.contains(criteria); 39 | const path = targetNode.getPath(); 40 | const pathString = path 41 | .map((item) => item.get('id')) 42 | .join(','); 43 | ``` 44 | ```js 45 | function compareById(vector) { 46 | return (a, b) => { 47 | const aid = Number(a.get('id')); 48 | const bid = Number(b.get('id')); 49 | if (aid > bid) { 50 | return vector ? 1 : -1; 51 | } else if (aid < bid) { 52 | return vector ? -1 : 1; 53 | } else { 54 | return 0 55 | } 56 | }; 57 | } 58 | tree.sort(compareById(false)); // desc 59 | ``` 60 | The following are the other methods available. 61 | **** 62 | # Tree 63 | This is the class of tree management. 64 | 65 | ### Properties 66 | * **rootNode** Root tree node 67 | * type `Node` 68 | 69 | ### Methods 70 | * **contstructor(object)** 71 | * params 72 | * object - json `object`. Optional 73 | * return `IronTree` 74 | * example 75 | ```js 76 | const object = { id: 1, title: 'Root' }; 77 | const tree = new Tree(object); 78 | ``` 79 | * **.add(criteria, object)** Adds a node to the tree if the criterion is true. 80 | * params 81 | * criteria(Node) - `function` or `string`. If `string` then criteria is **"root"** 82 | * object - content for the node 83 | * return `IronTree` 84 | * examples 85 | ```js 86 | const object = { id: 1, title: 'Root' }; 87 | const tree = new Tree(); 88 | const resultTree = tree.add('root', object); 89 | ``` 90 | ```js 91 | const regularObject = { id:2, title: 'Node 2'} 92 | const resultTree = tree.add((parentNode) => { 93 | return parentNode.get('id') === 1; 94 | }, regularObject); 95 | ``` 96 | * **.remove(criteria)** Removes a node from a tree if the criterion is true. 97 | * params 98 | * criteria(Node) - return `boolean` 99 | * return `boolean` 100 | * examples 101 | ```js 102 | const result = tree.remove((currentNode) => { 103 | return currentNode.get('id') === 7; 104 | }); 105 | ``` 106 | * **.contains(criteria)** Searches for a node in a tree according to the criterion. 107 | * params 108 | * criteria(Node) - return `boolean` 109 | * return `Node` 110 | * examples 111 | ```js 112 | const targetNode = tree.contains((currentNode) => { 113 | return currentNode.get('id') === 7; 114 | }); 115 | ``` 116 | 117 | * **.sort(compare)** Sorts a tree. 118 | * params 119 | * compare(a:Node, b:Node) - comparison function 120 | * return `null` 121 | * examples 122 | ```js 123 | function compareById(vector) { 124 | return (a, b) => { 125 | const aid = Number(a.get('id')); 126 | const bid = Number(b.get('id')); 127 | if (aid > bid) { 128 | return vector ? 1 : -1; 129 | } else if (aid < bid) { 130 | return vector ? -1 : 1; 131 | } else { 132 | return 0 133 | } 134 | }; 135 | } 136 | tree.sort(compareById(false)); //Desc 137 | ``` 138 | * **.move(criteria, destination)** Moves the desired branch or node to the node or branch of the destination, according to the criteria. 139 | * params 140 | * criteria(Node) - callback 141 | * destination(Node) - callback 142 | * return `boolean` 143 | * examples 144 | ```js 145 | const search = (currentNode) => currentNode.get('id') === 7; 146 | const destination = (currentNode) => currentNode.get('id') === 3; 147 | const result = tree.move(search, destination); 148 | ``` 149 | * **.traversal(criteria, callback)** Bypasses the tree and, according to the criterion, calls a function for each node. 150 | * params 151 | * criteria(Node) - return `boolean` 152 | * callback(Node) 153 | * return `null` 154 | * examples 155 | ```js 156 | const criteria = (currentNode) => currentNode.get('id') === 7; 157 | tree.traversal(criteria, (currentNode) => { 158 | currentNode.set('some', true); 159 | }); 160 | ``` 161 | ```js 162 | tree.traversal(null, (currentNode) => { 163 | if (currentNode.get('id')%2 === 0) { 164 | currentNode.set('some', true); 165 | } 166 | }); 167 | ``` 168 | * **.toJson(options)** Represents a tree in the form of a json format. 169 | * params 170 | * options - `object`. Optional 171 | * empty_children - Type `boolean`. Allow empty children. Default `true` 172 | * key_children - Type `string`. Field name for children. Default `children` 173 | * return `object` 174 | * examples 175 | ```js 176 | const json = tree.toJson(); 177 | ``` 178 | **** 179 | 180 | # Node 181 | This is the node management class. 182 | 183 | ### Properties 184 | * **content** Content of the node 185 | * type `object` 186 | * **children** Children of the node 187 | * type `array` 188 | * **length** Number children of the node 189 | * type `number` 190 | 191 | ### Methods 192 | * **constructor(json)** 193 | * params 194 | * json - simple `json` object 195 | * examples 196 | ```js 197 | const rootContent = { 198 | id: 1, 199 | name: 'Root', 200 | } 201 | let node = new Node(rootContent); 202 | ``` 203 | 204 | * **.add(child)** Adding a child to the node. 205 | * return `Node` - created node 206 | * params 207 | * child - type `object`/json 208 | * examples 209 | ```js 210 | const rootContent = { 211 | id: 1, 212 | name: 'Root', 213 | } 214 | let node = new Node(rootContent); 215 | const childNode = node.add({ id: 2, name: 'Two node'}); 216 | ``` 217 | * **.remove(criteria)** Removing a child node according to the criterion. 218 | * return - removed `Node` 219 | * params 220 | * criteria - criteria function for removing nodes 221 | * examples 222 | ```js 223 | const removedNodes = node.remove((itemNode) => { 224 | return itemNode.get('id') === 3; 225 | }) 226 | ``` 227 | 228 | * **.get(path)** Access to node content by field name. 229 | * return `mixed` 230 | * params 231 | * path - key name for object in node. For example `id` or `fullname`, etc... 232 | * examples 233 | ```js 234 | node.get('id'); // 1 235 | node.get('name') // "Some name" 236 | ``` 237 | * **.set(path, value)** Setting a value or creating a new field in the contents of a node. 238 | * return `boolean` 239 | * params 240 | * path - `String` field name 241 | * value - `mixed` 242 | * examples 243 | ```js 244 | node.set('id', 100)); // returned `true`. Node.content.id = 100 245 | node.get('id'); // 100 246 | ``` 247 | * **.sort(compare)** Sorting child nodes 248 | * return `null` 249 | * params 250 | * compare - custom function for sorting 251 | * examples 252 | ```js 253 | function compareById(vector) { 254 | return (a, b) => { 255 | const aid = Number(a.get('id')); 256 | const bid = Number(b.get('id')); 257 | if (aid > bid) { 258 | return vector ? 1 : -1; 259 | } else if (aid < bid) { 260 | return vector ? -1 : 1; 261 | } else { 262 | return 0 263 | } 264 | }; 265 | } 266 | node.sort(compareById(false)); 267 | ``` 268 | * **.traversal(criteria, callback)** Bypassing child nodes according to the criterion and applying function to them. 269 | * return `null` 270 | * params 271 | * criteria - `function` criteria each nodes 272 | * callback - `function` fire when criteria is true for node 273 | * examples 274 | ```js 275 | // for all nodes 276 | node.traversal(null, (currentNode) => { 277 | const name = currentNode.get('name'); 278 | currentNode.set('name', `${name}!`); // Last symbol "!" 279 | }); 280 | ``` 281 | ```js 282 | // only for node.id == 3 283 | node.traversal((currentNode) => currentNode.get('id') === 3, (currentNode) => { 284 | const name = currentNode.get('name'); 285 | currentNode.set('name', `${name}!`); // Last symbol "!" 286 | }); 287 | ``` 288 | 289 | * **.getPath()** This method return array Nodes from `root node` to `current node`. It maybe helpful for breadcrumbs. 290 | * return `Array` 291 | * exampels 292 | ```js 293 | const path = targetNode.getPath(); 294 | const pathString = path 295 | .map((item) => item.get('id')) 296 | .join(','); // 1,3,4,5,6 297 | ``` 298 | 299 | **** 300 | 301 | ## TDD 302 | `npm test` 303 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | var Tree = require('../src/tree.js') 2 | 3 | module.exports = Tree; 4 | -------------------------------------------------------------------------------- /fakes/generate-tree-default.js: -------------------------------------------------------------------------------- 1 | const Tree = require('../dist/index'); 2 | 3 | module.exports = function() { 4 | const object = {id: 1, title: 'Root'}; 5 | const tree = new Tree(object); 6 | 7 | const list = [ 8 | { id: 2, parent: 1 }, 9 | { id: 3, parent: 1 }, 10 | { id: 4, parent: 3 }, 11 | { id: 5, parent: 4 }, 12 | { id: 6, parent: 5 }, 13 | { id: 7, parent: 2 }, 14 | { id: 8, parent: 7 }, 15 | ] 16 | .map((item) => { 17 | item.title = `Node ${item.id}`; 18 | return item; 19 | }) 20 | .forEach((item) => { 21 | tree.add((parentNode) => { 22 | return parentNode.get('id') === item.parent; 23 | }, item); 24 | }); 25 | 26 | return tree; 27 | }; 28 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@denq/iron-tree", 3 | "version": "1.3.2", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@ungap/promise-all-settled": { 8 | "version": "1.1.2", 9 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 10 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 11 | "dev": true 12 | }, 13 | "ansi-colors": { 14 | "version": "4.1.1", 15 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 16 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 17 | "dev": true 18 | }, 19 | "ansi-regex": { 20 | "version": "5.0.1", 21 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 22 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 23 | "dev": true 24 | }, 25 | "ansi-styles": { 26 | "version": "4.3.0", 27 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 28 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 29 | "dev": true, 30 | "requires": { 31 | "color-convert": "^2.0.1" 32 | } 33 | }, 34 | "anymatch": { 35 | "version": "3.1.2", 36 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 37 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 38 | "dev": true, 39 | "requires": { 40 | "normalize-path": "^3.0.0", 41 | "picomatch": "^2.0.4" 42 | } 43 | }, 44 | "argparse": { 45 | "version": "2.0.1", 46 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 47 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 48 | "dev": true 49 | }, 50 | "assertion-error": { 51 | "version": "1.1.0", 52 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 53 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 54 | "dev": true 55 | }, 56 | "balanced-match": { 57 | "version": "1.0.2", 58 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 59 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 60 | "dev": true 61 | }, 62 | "binary-extensions": { 63 | "version": "2.2.0", 64 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 65 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 66 | "dev": true 67 | }, 68 | "brace-expansion": { 69 | "version": "1.1.11", 70 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 71 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 72 | "dev": true, 73 | "requires": { 74 | "balanced-match": "^1.0.0", 75 | "concat-map": "0.0.1" 76 | } 77 | }, 78 | "braces": { 79 | "version": "3.0.2", 80 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 81 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 82 | "dev": true, 83 | "requires": { 84 | "fill-range": "^7.0.1" 85 | } 86 | }, 87 | "browser-stdout": { 88 | "version": "1.3.1", 89 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 90 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 91 | "dev": true 92 | }, 93 | "camelcase": { 94 | "version": "6.3.0", 95 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 96 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 97 | "dev": true 98 | }, 99 | "chai": { 100 | "version": "4.3.6", 101 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", 102 | "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", 103 | "dev": true, 104 | "requires": { 105 | "assertion-error": "^1.1.0", 106 | "check-error": "^1.0.2", 107 | "deep-eql": "^3.0.1", 108 | "get-func-name": "^2.0.0", 109 | "loupe": "^2.3.1", 110 | "pathval": "^1.1.1", 111 | "type-detect": "^4.0.5" 112 | } 113 | }, 114 | "chalk": { 115 | "version": "4.1.2", 116 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 117 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 118 | "dev": true, 119 | "requires": { 120 | "ansi-styles": "^4.1.0", 121 | "supports-color": "^7.1.0" 122 | }, 123 | "dependencies": { 124 | "supports-color": { 125 | "version": "7.2.0", 126 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 127 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 128 | "dev": true, 129 | "requires": { 130 | "has-flag": "^4.0.0" 131 | } 132 | } 133 | } 134 | }, 135 | "check-error": { 136 | "version": "1.0.2", 137 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 138 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 139 | "dev": true 140 | }, 141 | "chokidar": { 142 | "version": "3.5.3", 143 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 144 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 145 | "dev": true, 146 | "requires": { 147 | "anymatch": "~3.1.2", 148 | "braces": "~3.0.2", 149 | "fsevents": "~2.3.2", 150 | "glob-parent": "~5.1.2", 151 | "is-binary-path": "~2.1.0", 152 | "is-glob": "~4.0.1", 153 | "normalize-path": "~3.0.0", 154 | "readdirp": "~3.6.0" 155 | } 156 | }, 157 | "cliui": { 158 | "version": "7.0.4", 159 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 160 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 161 | "dev": true, 162 | "requires": { 163 | "string-width": "^4.2.0", 164 | "strip-ansi": "^6.0.0", 165 | "wrap-ansi": "^7.0.0" 166 | } 167 | }, 168 | "color-convert": { 169 | "version": "2.0.1", 170 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 171 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 172 | "dev": true, 173 | "requires": { 174 | "color-name": "~1.1.4" 175 | } 176 | }, 177 | "color-name": { 178 | "version": "1.1.4", 179 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 180 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 181 | "dev": true 182 | }, 183 | "concat-map": { 184 | "version": "0.0.1", 185 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 186 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 187 | "dev": true 188 | }, 189 | "debug": { 190 | "version": "4.3.3", 191 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 192 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 193 | "dev": true, 194 | "requires": { 195 | "ms": "2.1.2" 196 | }, 197 | "dependencies": { 198 | "ms": { 199 | "version": "2.1.2", 200 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 201 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 202 | "dev": true 203 | } 204 | } 205 | }, 206 | "decamelize": { 207 | "version": "4.0.0", 208 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 209 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 210 | "dev": true 211 | }, 212 | "deep-eql": { 213 | "version": "3.0.1", 214 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 215 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 216 | "dev": true, 217 | "requires": { 218 | "type-detect": "^4.0.0" 219 | } 220 | }, 221 | "diff": { 222 | "version": "5.0.0", 223 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 224 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 225 | "dev": true 226 | }, 227 | "emoji-regex": { 228 | "version": "8.0.0", 229 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 230 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 231 | "dev": true 232 | }, 233 | "escalade": { 234 | "version": "3.1.1", 235 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 236 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 237 | "dev": true 238 | }, 239 | "escape-string-regexp": { 240 | "version": "4.0.0", 241 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 242 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 243 | "dev": true 244 | }, 245 | "fill-range": { 246 | "version": "7.0.1", 247 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 248 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 249 | "dev": true, 250 | "requires": { 251 | "to-regex-range": "^5.0.1" 252 | } 253 | }, 254 | "find-up": { 255 | "version": "5.0.0", 256 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 257 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 258 | "dev": true, 259 | "requires": { 260 | "locate-path": "^6.0.0", 261 | "path-exists": "^4.0.0" 262 | } 263 | }, 264 | "flat": { 265 | "version": "5.0.2", 266 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 267 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 268 | "dev": true 269 | }, 270 | "fs.realpath": { 271 | "version": "1.0.0", 272 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 273 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 274 | "dev": true 275 | }, 276 | "fsevents": { 277 | "version": "2.3.2", 278 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 279 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 280 | "dev": true, 281 | "optional": true 282 | }, 283 | "get-caller-file": { 284 | "version": "2.0.5", 285 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 286 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 287 | "dev": true 288 | }, 289 | "get-func-name": { 290 | "version": "2.0.0", 291 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 292 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 293 | "dev": true 294 | }, 295 | "glob": { 296 | "version": "7.2.0", 297 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 298 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 299 | "dev": true, 300 | "requires": { 301 | "fs.realpath": "^1.0.0", 302 | "inflight": "^1.0.4", 303 | "inherits": "2", 304 | "minimatch": "^3.0.4", 305 | "once": "^1.3.0", 306 | "path-is-absolute": "^1.0.0" 307 | }, 308 | "dependencies": { 309 | "minimatch": { 310 | "version": "3.1.2", 311 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 312 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 313 | "dev": true, 314 | "requires": { 315 | "brace-expansion": "^1.1.7" 316 | } 317 | } 318 | } 319 | }, 320 | "glob-parent": { 321 | "version": "5.1.2", 322 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 323 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 324 | "dev": true, 325 | "requires": { 326 | "is-glob": "^4.0.1" 327 | } 328 | }, 329 | "growl": { 330 | "version": "1.10.5", 331 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 332 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 333 | "dev": true 334 | }, 335 | "has-flag": { 336 | "version": "4.0.0", 337 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 338 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 339 | "dev": true 340 | }, 341 | "he": { 342 | "version": "1.2.0", 343 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 344 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 345 | "dev": true 346 | }, 347 | "inflight": { 348 | "version": "1.0.6", 349 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 350 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 351 | "dev": true, 352 | "requires": { 353 | "once": "^1.3.0", 354 | "wrappy": "1" 355 | } 356 | }, 357 | "inherits": { 358 | "version": "2.0.4", 359 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 360 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 361 | "dev": true 362 | }, 363 | "is-binary-path": { 364 | "version": "2.1.0", 365 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 366 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 367 | "dev": true, 368 | "requires": { 369 | "binary-extensions": "^2.0.0" 370 | } 371 | }, 372 | "is-extglob": { 373 | "version": "2.1.1", 374 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 375 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 376 | "dev": true 377 | }, 378 | "is-fullwidth-code-point": { 379 | "version": "3.0.0", 380 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 381 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 382 | "dev": true 383 | }, 384 | "is-glob": { 385 | "version": "4.0.3", 386 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 387 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 388 | "dev": true, 389 | "requires": { 390 | "is-extglob": "^2.1.1" 391 | } 392 | }, 393 | "is-number": { 394 | "version": "7.0.0", 395 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 396 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 397 | "dev": true 398 | }, 399 | "is-plain-obj": { 400 | "version": "2.1.0", 401 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 402 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 403 | "dev": true 404 | }, 405 | "is-unicode-supported": { 406 | "version": "0.1.0", 407 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 408 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 409 | "dev": true 410 | }, 411 | "isexe": { 412 | "version": "2.0.0", 413 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 414 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 415 | "dev": true 416 | }, 417 | "js-yaml": { 418 | "version": "4.1.0", 419 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 420 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 421 | "dev": true, 422 | "requires": { 423 | "argparse": "^2.0.1" 424 | } 425 | }, 426 | "locate-path": { 427 | "version": "6.0.0", 428 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 429 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 430 | "dev": true, 431 | "requires": { 432 | "p-locate": "^5.0.0" 433 | } 434 | }, 435 | "log-symbols": { 436 | "version": "4.1.0", 437 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 438 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 439 | "dev": true, 440 | "requires": { 441 | "chalk": "^4.1.0", 442 | "is-unicode-supported": "^0.1.0" 443 | } 444 | }, 445 | "loupe": { 446 | "version": "2.3.4", 447 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", 448 | "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", 449 | "dev": true, 450 | "requires": { 451 | "get-func-name": "^2.0.0" 452 | } 453 | }, 454 | "minimatch": { 455 | "version": "4.2.1", 456 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", 457 | "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", 458 | "dev": true, 459 | "requires": { 460 | "brace-expansion": "^1.1.7" 461 | } 462 | }, 463 | "mocha": { 464 | "version": "9.2.2", 465 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", 466 | "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", 467 | "dev": true, 468 | "requires": { 469 | "@ungap/promise-all-settled": "1.1.2", 470 | "ansi-colors": "4.1.1", 471 | "browser-stdout": "1.3.1", 472 | "chokidar": "3.5.3", 473 | "debug": "4.3.3", 474 | "diff": "5.0.0", 475 | "escape-string-regexp": "4.0.0", 476 | "find-up": "5.0.0", 477 | "glob": "7.2.0", 478 | "growl": "1.10.5", 479 | "he": "1.2.0", 480 | "js-yaml": "4.1.0", 481 | "log-symbols": "4.1.0", 482 | "minimatch": "4.2.1", 483 | "ms": "2.1.3", 484 | "nanoid": "3.3.1", 485 | "serialize-javascript": "6.0.0", 486 | "strip-json-comments": "3.1.1", 487 | "supports-color": "8.1.1", 488 | "which": "2.0.2", 489 | "workerpool": "6.2.0", 490 | "yargs": "16.2.0", 491 | "yargs-parser": "20.2.4", 492 | "yargs-unparser": "2.0.0" 493 | } 494 | }, 495 | "ms": { 496 | "version": "2.1.3", 497 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 498 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 499 | "dev": true 500 | }, 501 | "nanoid": { 502 | "version": "3.3.1", 503 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", 504 | "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", 505 | "dev": true 506 | }, 507 | "normalize-path": { 508 | "version": "3.0.0", 509 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 510 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 511 | "dev": true 512 | }, 513 | "once": { 514 | "version": "1.4.0", 515 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 516 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 517 | "dev": true, 518 | "requires": { 519 | "wrappy": "1" 520 | } 521 | }, 522 | "p-limit": { 523 | "version": "3.1.0", 524 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 525 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 526 | "dev": true, 527 | "requires": { 528 | "yocto-queue": "^0.1.0" 529 | } 530 | }, 531 | "p-locate": { 532 | "version": "5.0.0", 533 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 534 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 535 | "dev": true, 536 | "requires": { 537 | "p-limit": "^3.0.2" 538 | } 539 | }, 540 | "path-exists": { 541 | "version": "4.0.0", 542 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 543 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 544 | "dev": true 545 | }, 546 | "path-is-absolute": { 547 | "version": "1.0.1", 548 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 549 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 550 | "dev": true 551 | }, 552 | "pathval": { 553 | "version": "1.1.1", 554 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 555 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 556 | "dev": true 557 | }, 558 | "picomatch": { 559 | "version": "2.3.1", 560 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 561 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 562 | "dev": true 563 | }, 564 | "randombytes": { 565 | "version": "2.1.0", 566 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 567 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 568 | "dev": true, 569 | "requires": { 570 | "safe-buffer": "^5.1.0" 571 | } 572 | }, 573 | "readdirp": { 574 | "version": "3.6.0", 575 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 576 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 577 | "dev": true, 578 | "requires": { 579 | "picomatch": "^2.2.1" 580 | } 581 | }, 582 | "require-directory": { 583 | "version": "2.1.1", 584 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 585 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 586 | "dev": true 587 | }, 588 | "safe-buffer": { 589 | "version": "5.2.1", 590 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 591 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 592 | "dev": true 593 | }, 594 | "serialize-javascript": { 595 | "version": "6.0.0", 596 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 597 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 598 | "dev": true, 599 | "requires": { 600 | "randombytes": "^2.1.0" 601 | } 602 | }, 603 | "string-width": { 604 | "version": "4.2.3", 605 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 606 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 607 | "dev": true, 608 | "requires": { 609 | "emoji-regex": "^8.0.0", 610 | "is-fullwidth-code-point": "^3.0.0", 611 | "strip-ansi": "^6.0.1" 612 | } 613 | }, 614 | "strip-ansi": { 615 | "version": "6.0.1", 616 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 617 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 618 | "dev": true, 619 | "requires": { 620 | "ansi-regex": "^5.0.1" 621 | } 622 | }, 623 | "strip-json-comments": { 624 | "version": "3.1.1", 625 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 626 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 627 | "dev": true 628 | }, 629 | "supports-color": { 630 | "version": "8.1.1", 631 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 632 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 633 | "dev": true, 634 | "requires": { 635 | "has-flag": "^4.0.0" 636 | } 637 | }, 638 | "to-regex-range": { 639 | "version": "5.0.1", 640 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 641 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 642 | "dev": true, 643 | "requires": { 644 | "is-number": "^7.0.0" 645 | } 646 | }, 647 | "type-detect": { 648 | "version": "4.0.8", 649 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 650 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 651 | "dev": true 652 | }, 653 | "which": { 654 | "version": "2.0.2", 655 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 656 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 657 | "dev": true, 658 | "requires": { 659 | "isexe": "^2.0.0" 660 | } 661 | }, 662 | "workerpool": { 663 | "version": "6.2.0", 664 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", 665 | "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", 666 | "dev": true 667 | }, 668 | "wrap-ansi": { 669 | "version": "7.0.0", 670 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 671 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 672 | "dev": true, 673 | "requires": { 674 | "ansi-styles": "^4.0.0", 675 | "string-width": "^4.1.0", 676 | "strip-ansi": "^6.0.0" 677 | } 678 | }, 679 | "wrappy": { 680 | "version": "1.0.2", 681 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 682 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 683 | "dev": true 684 | }, 685 | "y18n": { 686 | "version": "5.0.8", 687 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 688 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 689 | "dev": true 690 | }, 691 | "yargs": { 692 | "version": "16.2.0", 693 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 694 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 695 | "dev": true, 696 | "requires": { 697 | "cliui": "^7.0.2", 698 | "escalade": "^3.1.1", 699 | "get-caller-file": "^2.0.5", 700 | "require-directory": "^2.1.1", 701 | "string-width": "^4.2.0", 702 | "y18n": "^5.0.5", 703 | "yargs-parser": "^20.2.2" 704 | } 705 | }, 706 | "yargs-parser": { 707 | "version": "20.2.4", 708 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 709 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 710 | "dev": true 711 | }, 712 | "yargs-unparser": { 713 | "version": "2.0.0", 714 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 715 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 716 | "dev": true, 717 | "requires": { 718 | "camelcase": "^6.0.0", 719 | "decamelize": "^4.0.0", 720 | "flat": "^5.0.2", 721 | "is-plain-obj": "^2.1.0" 722 | } 723 | }, 724 | "yocto-queue": { 725 | "version": "0.1.0", 726 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 727 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 728 | "dev": true 729 | } 730 | } 731 | } 732 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@denq/iron-tree", 3 | "version": "1.3.3", 4 | "description": "Build tree and many method for manipulation", 5 | "main": "./dist/index.js", 6 | "scripts": { 7 | "test": "mocha --timeout 10000" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/DenQ/iron-tree.git" 12 | }, 13 | "keywords": [ 14 | "tree", 15 | "node", 16 | "criteria", 17 | "iron-tree", 18 | "sort tree", 19 | "remove nodes", 20 | "contains", 21 | "move nodes", 22 | "toJson" 23 | ], 24 | "author": "DenQ", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/DenQ/iron-tree/issues" 28 | }, 29 | "homepage": "https://github.com/DenQ/iron-tree#readme", 30 | "devDependencies": { 31 | "chai": "^4.3.6", 32 | "mocha": "^9.2.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/node.js: -------------------------------------------------------------------------------- 1 | module.exports = class Node { 2 | 3 | constructor(content) { 4 | this.content = content; 5 | this.children = []; 6 | this.length = 0; 7 | } 8 | 9 | get(fieldKey) { 10 | if (typeof this.content[fieldKey] !== 'undefined') { 11 | return this.content[fieldKey]; 12 | } 13 | } 14 | 15 | set(fieldKey, value) { 16 | return !!(this.content[fieldKey] = value); 17 | } 18 | 19 | add(child) { 20 | const node = (child instanceof Node) ? child : new Node(child); 21 | node.parent = this; 22 | this.length++; 23 | this.children.push(node); 24 | return node; 25 | } 26 | 27 | remove(callback) { 28 | const index = this.children.findIndex(callback); 29 | if (index > -1) { 30 | const removeItems = this.children.splice(index, 1); 31 | this.length--; 32 | return removeItems; 33 | } return []; 34 | } 35 | 36 | sort(compare) { 37 | return this.children.sort(compare); 38 | } 39 | 40 | traversal(criteria, callback) { 41 | criteria = criteria || (() => true); 42 | this.children 43 | .filter(criteria) 44 | .forEach(callback); 45 | } 46 | 47 | getPath() { 48 | const parentList = []; 49 | let currentNode = this; 50 | while(currentNode) { 51 | parentList.push(currentNode); 52 | currentNode = currentNode.parent; 53 | } 54 | return parentList.reverse(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/tree.js: -------------------------------------------------------------------------------- 1 | const Node = require('./node'); 2 | const searchNode = require('../utils/search-node'); 3 | const traversalTree = require('../utils/traversal-tree'); 4 | const serializeTree = require('../utils/serialize-tree'); 5 | const removeEmptyChildren = require('../utils/remove-empty-children'); 6 | 7 | class Tree { 8 | 9 | constructor(object = undefined) { 10 | this.rootNode = null; 11 | if (object) { 12 | this.rootNode = new Node(object); 13 | } 14 | } 15 | 16 | // only for rootNode 17 | get(path) { 18 | return this.rootNode.get(path); 19 | } 20 | 21 | // only for rootNode 22 | set(path, value) { 23 | this.rootNode.set(path, value); 24 | } 25 | 26 | add(callback, object) { 27 | const type = typeof callback; 28 | if (type === 'string' && callback === 'root') { 29 | this.rootNode = new Node(object); 30 | return this; 31 | } else if (type === 'function') { 32 | const target = searchNode(this, null, callback); 33 | if (target && target.add(object)) { 34 | return this; 35 | } else { 36 | console.log('Warning', object); 37 | } 38 | } 39 | } 40 | 41 | contains(criteria) { 42 | return searchNode(this, null, criteria); 43 | } 44 | 45 | remove(criteria) { 46 | const targetNode = this.contains(criteria); 47 | if (targetNode) { 48 | return !!targetNode.parent.remove(criteria); 49 | } 50 | return false; 51 | } 52 | 53 | move(search, destination) { 54 | const targetNode = this.contains(search); 55 | if (targetNode && this.remove(search)) { 56 | const destinationNode = this.contains(destination); 57 | return !!destinationNode.add(targetNode); 58 | } 59 | return false; 60 | } 61 | 62 | traversal(criteria, callback) { 63 | traversalTree(this, null, criteria, callback); 64 | } 65 | 66 | sort(compare) { 67 | this.traversal(null, (currentNode) => { 68 | currentNode.sort(compare); 69 | }); 70 | } 71 | 72 | toJson(options = {}) { 73 | const optionsDefault = { 74 | key_children: 'children', 75 | empty_children: true, 76 | }; 77 | options = Object.assign(optionsDefault, options); 78 | const result = serializeTree(this, null, [], options); 79 | 80 | if (!options.empty_children) { 81 | removeEmptyChildren(result, null, options); 82 | } 83 | 84 | if (result && result.length > 0) { 85 | return result[0]; 86 | } 87 | } 88 | } 89 | 90 | Tree.Node = Node; 91 | 92 | module.exports = Tree; -------------------------------------------------------------------------------- /test/node-test.js: -------------------------------------------------------------------------------- 1 | const { assert, expect } = require('chai'); 2 | 3 | const Node = require('../dist/index').Node; 4 | const compareById = require('../utils/node-compare-by-id'); 5 | 6 | 7 | 8 | const rootContent = { 9 | id: 1, 10 | name: 'Root', 11 | } 12 | let node = new Node(rootContent); 13 | 14 | describe('Node', function() { 15 | beforeEach(function() { 16 | node = new Node(rootContent); 17 | }); 18 | 19 | describe('Constructor', function() { 20 | 21 | it('Check children and content field', function() { 22 | const { children, content } = node; 23 | 24 | assert.isArray(children); 25 | expect(children).to.have.lengthOf(0); 26 | expect(content.name).to.equal(rootContent.name); 27 | }); 28 | 29 | it('Check correct work getter', function() { 30 | assert.equal(rootContent.name, node.get('name')); 31 | expect(node.get('lastname')).to.equal(undefined); 32 | }); 33 | 34 | }); 35 | 36 | 37 | describe('Get', function() { 38 | 39 | it('Method get with correct path', function() { 40 | expect(node.get('id')).to.equal(1); 41 | expect(node.get('name')).to.equal('Root'); 42 | }); 43 | 44 | it('Method get with incorrect path', function() { 45 | expect(node.get('uid')).to.equal(undefined); 46 | }); 47 | 48 | }); 49 | 50 | describe('Set', function() { 51 | 52 | it('Method set with correct path', function() { 53 | expect(node.set('id', 100)).to.equal(true); 54 | expect(node.get('id')).to.equal(100); 55 | }); 56 | 57 | it('Method set with incorrect path', function() { 58 | expect(node.set('uid', 101)).to.equal(true); 59 | expect(node.get('uid')).to.equal(101); 60 | }); 61 | 62 | }); 63 | 64 | 65 | describe('Add', function() { 66 | 67 | it('Add one node', function() { 68 | const childNode = node.add({ id: 2, name: 'Two node'}); 69 | 70 | expect(childNode instanceof Node).to.equal(true); 71 | expect(node.children).to.have.lengthOf(1); 72 | expect(node.length).to.equal(1); 73 | }); 74 | 75 | it('Add nodes', function() { 76 | node.add({ id: 2, name: 'Two node'}); 77 | node.add({ id: 3, name: 'Three node'}); 78 | 79 | expect(node.children).to.have.lengthOf(2); 80 | expect(node.length).to.equal(2); 81 | }); 82 | 83 | }); 84 | 85 | 86 | describe('Remove', function() { 87 | 88 | it('Remove exists child node', function() { 89 | node.add({ id: 2, name: 'Two node'}); 90 | node.add({ id: 3, name: 'Three node'}); 91 | const removedNodes = node.remove((itemNode) => { 92 | return itemNode.get('id') === 3; 93 | }); 94 | 95 | expect(node.length).to.equal(1); 96 | expect(removedNodes.length).to.equal(1); 97 | }); 98 | 99 | it('Remove not exists node', function() { 100 | node.add({ id: 2, name: 'Two node'}); 101 | node.add({ id: 3, name: 'Three node'}); 102 | const removedNodes = node.remove((itemNode) => { 103 | return itemNode.get('id') === 333; 104 | }); 105 | 106 | expect(node.length).to.equal(2); 107 | expect(removedNodes.length).to.equal(0); 108 | }); 109 | 110 | }); 111 | 112 | 113 | describe('Sort', function() { 114 | 115 | it('Order desc', function() { 116 | node.add({ id: 2, name: 'Two node'}); 117 | node.add({ id: 3, name: 'Three node'}); 118 | node.add({ id: 15, name: 'Fifteen node'}); 119 | node.add({ id: 4, name: 'Four node'}); 120 | node.sort(compareById(false)); 121 | 122 | expect(node.children[0].get('id')).to.equal(15); 123 | expect(node.children[1].get('id')).to.equal(4); 124 | expect(node.children[2].get('id')).to.equal(3); 125 | expect(node.children[3].get('id')).to.equal(2); 126 | }); 127 | 128 | it('Order asc', function() { 129 | node.add({ id: 2, name: 'Two node'}); 130 | node.add({ id: 3, name: 'Three node'}); 131 | node.add({ id: 15, name: 'Fifteen node'}); 132 | node.add({ id: 4, name: 'Four node'}); 133 | node.sort(compareById(true)); 134 | 135 | expect(node.children[0].get('id')).to.equal(2); 136 | expect(node.children[1].get('id')).to.equal(3); 137 | expect(node.children[2].get('id')).to.equal(4); 138 | expect(node.children[3].get('id')).to.equal(15); 139 | }); 140 | 141 | }); 142 | 143 | 144 | describe('Traversal', function() { 145 | 146 | it('Change name for each child', function() { 147 | node.add({ id: 2, name: 'Two node'}); 148 | node.add({ id: 3, name: 'Three node'}); 149 | node.add({ id: 15, name: 'Fifteen node'}); 150 | node.add({ id: 4, name: 'Four node'}); 151 | node.traversal(null, (currentNode) => { 152 | const name = currentNode.get('name'); 153 | currentNode.set('name', `${name}!`); 154 | }); 155 | expect(node.children[0].get('name')).to.equal('Two node!'); 156 | expect(node.children[1].get('name')).to.equal('Three node!'); 157 | }); 158 | 159 | it('Change name for item with id is 3', function() { 160 | node.add({ id: 2, name: 'Two node'}); 161 | node.add({ id: 3, name: 'Three node'}); 162 | node.add({ id: 15, name: 'Fifteen node'}); 163 | node.add({ id: 4, name: 'Four node'}); 164 | node.traversal((currentNode) => currentNode.get('id') === 3, (currentNode) => { 165 | const name = currentNode.get('name'); 166 | currentNode.set('name', `${name}!`); 167 | }); 168 | expect(node.children[0].get('name')).to.equal('Two node'); 169 | expect(node.children[1].get('name')).to.equal('Three node!'); 170 | }); 171 | 172 | }); 173 | 174 | }); 175 | -------------------------------------------------------------------------------- /test/tree-test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require('chai'); 2 | 3 | const compareById = require('../utils/node-compare-by-id'); 4 | const generateTreeDefault = require('../fakes/generate-tree-default'); 5 | const Tree = require('../dist/index'); 6 | 7 | const { Node } = Tree; 8 | 9 | 10 | let object = { id: 1, title: 'Root' }; 11 | let tree = new Tree(object); 12 | 13 | describe('Tree', function() { 14 | beforeEach(function() { 15 | object = { id: 1, title: 'Root' }; 16 | tree = new Tree(object); 17 | }); 18 | 19 | describe('Constructor', function() { 20 | 21 | it('It exists', function() { 22 | expect(tree instanceof Tree).to.equal(true); 23 | }); 24 | 25 | it('With params', function() { 26 | expect(tree.rootNode instanceof Node).to.equal(true); 27 | }); 28 | 29 | it('Without params', function() { 30 | const tree = new Tree(); 31 | 32 | expect(tree.rootNode instanceof Node).to.equal(false); 33 | expect(tree.rootNode).to.equal(null); 34 | }); 35 | 36 | }); 37 | 38 | 39 | describe('Add', function() { 40 | 41 | it('Add root', function() { 42 | const tree = new Tree(); 43 | const resultTree = tree.add('root', object); 44 | 45 | expect(resultTree instanceof Tree).to.equal(true); 46 | expect(resultTree.rootNode instanceof Node).to.equal(true); 47 | }); 48 | 49 | it('Add regular node', function() { 50 | const regularObject = { id:2, title: 'Node 2'} 51 | const resultTree = tree.add((parentNode) => { 52 | return parentNode.get('id') === 1; 53 | }, regularObject); 54 | 55 | expect(resultTree instanceof Tree).to.equal(true); 56 | expect(resultTree.rootNode instanceof Node).to.equal(true); 57 | 58 | expect(resultTree.rootNode.children).to.have.lengthOf(1); 59 | expect(resultTree.rootNode.children[0].get('id')).to.equal(2); 60 | }); 61 | 62 | it('Add many nodes', function() { 63 | tree = generateTreeDefault(); 64 | 65 | expect(tree instanceof Tree).to.equal(true); 66 | expect(tree.rootNode instanceof Node).to.equal(true); 67 | 68 | expect(tree.rootNode.get('id')).to.equal(1); 69 | expect(tree.rootNode.children[0].get('id')).to.equal(2); 70 | expect(tree.rootNode.children[1].get('id')).to.equal(3); 71 | 72 | expect(tree.rootNode.children[1].children[0].get('id')).to.equal(4); 73 | expect(tree.rootNode.children[1].children[0].children[0].get('id')).to.equal(5); 74 | expect(tree.rootNode.children[1].children[0].children[0].children[0].get('id')).to.equal(6); 75 | 76 | // showTree(tree); 77 | }); 78 | }); 79 | 80 | 81 | describe('Contains', function() { 82 | 83 | it('Search element when he does exists', function() { 84 | tree = generateTreeDefault(); 85 | const targetNode = tree.contains((currentNode) => { 86 | return currentNode.get('id') === 7; 87 | }); 88 | 89 | expect(targetNode instanceof Node).to.equal(true); 90 | expect(targetNode.get('id')).to.equal(7); 91 | }); 92 | 93 | it('Search element when he does not exists', function() { 94 | tree = generateTreeDefault(); 95 | const targetNode = tree.contains((currentNode) => { 96 | return currentNode.get('id') === 100; 97 | }); 98 | 99 | expect(targetNode).to.equal(undefined); 100 | }); 101 | 102 | }); 103 | 104 | 105 | describe('Remove', function() { 106 | 107 | it('Remove correct criteria', function() { 108 | tree = generateTreeDefault(); 109 | const result = tree.remove((currentNode) => { 110 | return currentNode.get('id') === 7; 111 | }); 112 | const targetNode = tree.contains((currentNode) => { 113 | return currentNode.get('id') === 7; 114 | }); 115 | 116 | expect(result).to.equal(true); 117 | expect(targetNode).to.equal(undefined); 118 | }); 119 | 120 | it('Remove incorrect criteria', function() { 121 | tree = generateTreeDefault(); 122 | const result = tree.remove((currentNode) => { 123 | return currentNode.get('id') === 100; 124 | }); 125 | const targetNode = tree.contains((currentNode) => { 126 | return currentNode.get('id') === 100; 127 | }); 128 | 129 | expect(result).to.equal(false); 130 | expect(targetNode).to.equal(undefined); 131 | }); 132 | 133 | }); 134 | 135 | 136 | describe('Move', function() { 137 | 138 | it('Move exists branch', function() { 139 | tree = generateTreeDefault(); 140 | const search = (currentNode) => currentNode.get('id') === 7; 141 | const destination = (currentNode) => currentNode.get('id') === 3; 142 | const result = tree.move(search, destination); 143 | const targetNode = tree.contains(search); 144 | 145 | expect(result).to.equal(true); 146 | expect(targetNode.get('id')).to.equal(7); 147 | expect(targetNode.parent.get('id')).to.equal(3); 148 | 149 | // showTree(tree); 150 | }); 151 | 152 | it('Move not exists branch', function() { 153 | tree = generateTreeDefault(); 154 | const search = (currentNode) => currentNode.get('id') === 100 155 | const destination = (currentNode) => currentNode.get('id') === 3; 156 | const result = tree.move(search, destination); 157 | const targetNode = tree.contains(search); 158 | 159 | expect(result).to.equal(false); 160 | expect(targetNode).to.equal(undefined); 161 | }); 162 | 163 | }); 164 | 165 | 166 | describe('Traversal', function() { 167 | 168 | it('Add new field for item.id === 7', function() { 169 | tree = generateTreeDefault(); 170 | const criteria = (currentNode) => currentNode.get('id') === 7; 171 | tree.traversal(criteria, (currentNode) => { 172 | currentNode.set('some', true); 173 | }); 174 | // showTree(tree); 175 | tree.traversal(null, (currentNode) => { 176 | const some = currentNode.get('some'); 177 | expect(some).to.equal((currentNode.get('id') === 7) ? true : undefined ); 178 | }); 179 | }); 180 | 181 | it('Add new property for each node', function() { 182 | tree = generateTreeDefault(); 183 | tree.traversal(null, (currentNode) => { 184 | currentNode.set('some', true); 185 | }); 186 | 187 | tree.traversal(null, (currentNode) => { 188 | const some = currentNode.get('some'); 189 | expect(some).to.equal(true); 190 | }); 191 | }); 192 | 193 | it('Add new property only for even nodes', function() { 194 | tree = generateTreeDefault(); 195 | tree.traversal(null, (currentNode) => { 196 | if (currentNode.get('id')%2 === 0) { 197 | currentNode.set('some', true); 198 | } 199 | }); 200 | 201 | tree.traversal(null, (currentNode) => { 202 | const some = currentNode.get('some'); 203 | if (currentNode.get('id')%2 === 0) { 204 | expect(some).to.equal(true); 205 | } else { 206 | expect(some).to.equal(undefined); 207 | } 208 | }); 209 | }); 210 | 211 | }); 212 | 213 | 214 | describe('Sort', function() { 215 | 216 | it('Order desc', function() { 217 | tree = generateTreeDefault(); 218 | tree.sort(compareById(false)); 219 | 220 | // showTree(tree); 221 | expect(tree.rootNode.children[0].get('id')).to.equal(3); 222 | expect(tree.rootNode.children[1].get('id')).to.equal(2); 223 | }); 224 | 225 | it('Order asc', function() { 226 | tree = generateTreeDefault(); 227 | tree.sort(compareById(false)); 228 | tree.sort(compareById(true)); 229 | 230 | // showTree(tree); 231 | expect(tree.rootNode.children[0].get('id')).to.equal(2); 232 | expect(tree.rootNode.children[1].get('id')).to.equal(3); 233 | }); 234 | 235 | }); 236 | 237 | describe('getPath', () => { 238 | 239 | it('Get path 1 - 6', () => { 240 | tree = generateTreeDefault(); 241 | const criteria = (currentNode) => currentNode.get('id') === 6; 242 | const targetNode = tree.contains(criteria); 243 | const path = targetNode.getPath(); 244 | const pathString = path 245 | .map((item) => item.get('id')) 246 | .join(','); 247 | 248 | expect(pathString).to.equal('1,3,4,5,6'); 249 | }); 250 | 251 | it('Get path 1 - 8', () => { 252 | tree = generateTreeDefault(); 253 | const criteria = (currentNode) => currentNode.get('id') === 8; 254 | const targetNode = tree.contains(criteria); 255 | const path = targetNode.getPath(); 256 | const pathString = path 257 | .map((item) => item.get('id')) 258 | .join(','); 259 | 260 | expect(pathString).to.equal('1,2,7,8'); 261 | }); 262 | 263 | it('Get path 1 - 2', () => { 264 | tree = generateTreeDefault(); 265 | const criteria = (currentNode) => currentNode.get('id') === 2; 266 | const targetNode = tree.contains(criteria); 267 | const path = targetNode.getPath(); 268 | const pathString = path 269 | .map((item) => item.get('id')) 270 | .join(','); 271 | 272 | expect(pathString).to.equal('1,2'); 273 | }); 274 | 275 | }); 276 | 277 | 278 | describe('toJson', function() { 279 | 280 | it('Searialize tree to json', function() { 281 | tree = generateTreeDefault(); 282 | const json = tree.toJson(); 283 | 284 | expect(json.id).to.equal(1); 285 | expect(json.children[0].id).to.equal(2); 286 | expect(json.children[0].children[0].id).to.equal(7); 287 | expect(json.children[0].children[0].children[0].id).to.equal(8); 288 | expect(json.children[1].id).to.equal(3); 289 | expect(json.children[1].children[0].id).to.equal(4); 290 | expect(json.children[1].children[0].children[0].id).to.equal(5); 291 | }); 292 | 293 | it('Searialize tree to json after sort desc', function() { 294 | tree = generateTreeDefault(); 295 | tree.sort(compareById(false)); 296 | const json = tree.toJson(); 297 | 298 | expect(json.id).to.equal(1); 299 | expect(json.children[1].id).to.equal(2); 300 | expect(json.children[1].children[0].id).to.equal(7); 301 | expect(json.children[1].children[0].children[0].id).to.equal(8); 302 | expect(json.children[0].id).to.equal(3); 303 | expect(json.children[0].children[0].id).to.equal(4); 304 | expect(json.children[0].children[0].children[0].id).to.equal(5); 305 | }); 306 | 307 | it('Searialize tree to json after remove element', function() { 308 | tree = generateTreeDefault(); 309 | tree.remove((parentNode) => parentNode.get('id') === 2); 310 | const json = tree.toJson(); 311 | 312 | expect(json.id).to.equal(1); 313 | expect(json.children[0].id).to.equal(3); 314 | expect(json.children[0].children[0].id).to.equal(4); 315 | expect(json.children[0].children[0].children[0].id).to.equal(5); 316 | }); 317 | 318 | it('Searialize tree to json with options: key_children=child', function() { 319 | tree = generateTreeDefault(); 320 | const json = tree.toJson({ 321 | key_children: 'child', 322 | }); 323 | 324 | expect(json.id).to.equal(1); 325 | expect(json.child[0].id).to.equal(2); 326 | expect(json.child[0].child[0].id).to.equal(7); 327 | expect(json.child[0].child[0].child[0].id).to.equal(8); 328 | expect(json.child[1].id).to.equal(3); 329 | expect(json.child[1].child[0].id).to.equal(4); 330 | }); 331 | 332 | describe('Options', function() { 333 | 334 | it('Flag: empty_children', function() { 335 | tree = generateTreeDefault(); 336 | const json = tree.toJson({ 337 | empty_children: false, 338 | }); 339 | 340 | expect(json.children[0].children[0].children[0].id).to.equal(8); 341 | expect(json.children[0].children[0].children[0].children).to.equal(undefined); 342 | }); 343 | 344 | }); 345 | 346 | }); 347 | 348 | 349 | describe('Options', function() { 350 | 351 | it('Flags: key_id and key_parent', function() { 352 | const object = { uid: 1, title: 'Root'}; 353 | const tree = new Tree(object); 354 | 355 | const list = [ 356 | { uid: 2, _parent: 1 }, 357 | { uid: 3, _parent: 1 }, 358 | { uid: 4, _parent: 3 }, 359 | { uid: 5, _parent: 4 }, 360 | { uid: 6, _parent: 5 }, 361 | { uid: 7, _parent: 2 }, 362 | { uid: 8, _parent: 7 }, 363 | ] 364 | .map((item) => { 365 | item.title = `Node ${item.uid}`; 366 | return item; 367 | }) 368 | .forEach((item) => { 369 | tree.add((parentNode) => { 370 | return parentNode.get('uid') === item._parent; 371 | }, item); 372 | }); 373 | 374 | // showTree(tree); 375 | // console.log(tree.toJson({ key_children: 'child' })); 376 | 377 | expect(tree instanceof Tree).to.equal(true); 378 | expect(tree.rootNode instanceof Node).to.equal(true); 379 | 380 | expect(tree.rootNode.get('uid')).to.equal(1); 381 | expect(tree.rootNode.children[0].get('uid')).to.equal(2); 382 | expect(tree.rootNode.children[1].get('uid')).to.equal(3); 383 | 384 | expect(tree.rootNode.children[1].children[0].get('uid')).to.equal(4); 385 | expect(tree.rootNode.children[1].children[0].children[0].get('uid')).to.equal(5); 386 | expect(tree.rootNode.children[1].children[0].children[0].children[0].get('uid')).to.equal(6); 387 | 388 | }); 389 | 390 | }); 391 | 392 | 393 | describe('Get', function() { 394 | 395 | it('Regular', function() { 396 | expect(tree.get('id')).to.equal(1); 397 | }); 398 | 399 | it('If not exists property', function() { 400 | expect(tree.get('uid')).to.equal(undefined); 401 | }); 402 | 403 | }); 404 | 405 | 406 | describe('Set', function() { 407 | 408 | it('Regular set', function() { 409 | expect(tree.get('id')).to.equal(1); 410 | tree.set('id', 101); 411 | expect(tree.get('id')).to.equal(101); 412 | }); 413 | 414 | it('Add new property', function() { 415 | expect(tree.get('some')).to.equal(undefined); 416 | tree.set('some', true); 417 | expect(tree.get('some')).to.equal(true); 418 | }); 419 | 420 | }); 421 | 422 | 423 | describe('Hide load', function() { 424 | 425 | it('2000 items', function() { 426 | function getRandomInt(min, max) { 427 | return Math.floor(Math.random() * (max - min + 1)) + min; 428 | } 429 | const list = (new Array(10000)) 430 | .fill() 431 | .map((item, index) => { 432 | return { 433 | id: index + 1, 434 | parent: getRandomInt(0, index) 435 | } 436 | }); 437 | 438 | tree = new Tree({ id: 0 }); 439 | list.forEach((item, index) => { 440 | tree.add((parentNode) => { 441 | return parentNode.get('id') === item.parent; 442 | }, item); 443 | }); 444 | const jTree = tree.toJson({ 445 | empty_children: false, 446 | }); 447 | 448 | }); 449 | 450 | }); 451 | 452 | }); 453 | -------------------------------------------------------------------------------- /utils/node-compare-by-id.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Return callback to compare nodes by id 3 | * @param boolean vector If vector is true then sort asc else desc 4 | * @return function Compare function 5 | */ 6 | module.exports = function compareById(vector) { 7 | return (a, b) => { 8 | const aid = Number(a.get('id')); 9 | const bid = Number(b.get('id')); 10 | if (aid > bid) { 11 | return vector ? 1 : -1; 12 | } else if (aid < bid) { 13 | return vector ? -1 : 1; 14 | } else { 15 | return 0 16 | } 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /utils/remove-empty-children.js: -------------------------------------------------------------------------------- 1 | // for json tree 2 | module.exports = function removeEmptyChildren(jTree, node = null, options) { 3 | const { key_children } = options; 4 | node = node || jTree[0]; 5 | if (node[key_children].length === 0) { 6 | delete node[key_children]; 7 | } else { 8 | node[key_children].forEach((item) => { 9 | removeEmptyChildren(jTree, item, options); 10 | }); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /utils/search-node.js: -------------------------------------------------------------------------------- 1 | module.exports = function searchNode(tree, node, criteria, options) { 2 | const currentNode = node || tree.rootNode; 3 | if (criteria(currentNode)) { 4 | return currentNode; 5 | } 6 | const children = currentNode.children 7 | let target = null; 8 | for(let i=0; i { 8 | serializeTree(tree, item, target[index-1][key_children], options); 9 | }); 10 | return target; 11 | } 12 | -------------------------------------------------------------------------------- /utils/show-tree.js: -------------------------------------------------------------------------------- 1 | module.exports = function showTree(tree, node = null, level = 1) { 2 | node = node || tree.rootNode; 3 | console.log((new Array(level)).join('\t'), node.content); 4 | node.children.forEach((item) => { 5 | showTree(tree, item, level + 1); 6 | }); 7 | } 8 | -------------------------------------------------------------------------------- /utils/traversal-tree.js: -------------------------------------------------------------------------------- 1 | module.exports = function traversalTree(tree, node = null, criteria, callback) { 2 | const currentNode = node || tree.rootNode; 3 | if (!node) { 4 | if (typeof criteria === 'function' && criteria(currentNode)) { 5 | callback(currentNode); 6 | } else if (criteria === null) { 7 | callback(currentNode); 8 | } 9 | } 10 | currentNode.traversal(criteria, callback); 11 | const children = currentNode.children; 12 | 13 | children.forEach((item) => { 14 | traversalTree(tree, item, criteria, callback); 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ungap/promise-all-settled@1.1.2": 6 | version "1.1.2" 7 | resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" 8 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 9 | 10 | ansi-colors@4.1.1: 11 | version "4.1.1" 12 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 13 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 14 | 15 | ansi-regex@^5.0.1: 16 | version "5.0.1" 17 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 18 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 19 | 20 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 21 | version "4.3.0" 22 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 23 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 24 | dependencies: 25 | color-convert "^2.0.1" 26 | 27 | anymatch@~3.1.2: 28 | version "3.1.2" 29 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 30 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 31 | dependencies: 32 | normalize-path "^3.0.0" 33 | picomatch "^2.0.4" 34 | 35 | argparse@^2.0.1: 36 | version "2.0.1" 37 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 38 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 39 | 40 | assertion-error@^1.1.0: 41 | version "1.1.0" 42 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 43 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 44 | 45 | balanced-match@^1.0.0: 46 | version "1.0.2" 47 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 48 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 49 | 50 | binary-extensions@^2.0.0: 51 | version "2.2.0" 52 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 53 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 54 | 55 | brace-expansion@^1.1.7: 56 | version "1.1.11" 57 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 58 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 59 | dependencies: 60 | balanced-match "^1.0.0" 61 | concat-map "0.0.1" 62 | 63 | braces@~3.0.2: 64 | version "3.0.2" 65 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 66 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 67 | dependencies: 68 | fill-range "^7.0.1" 69 | 70 | browser-stdout@1.3.1: 71 | version "1.3.1" 72 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 73 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 74 | 75 | camelcase@^6.0.0: 76 | version "6.3.0" 77 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" 78 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 79 | 80 | chai@^4.3.6: 81 | version "4.3.6" 82 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" 83 | integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== 84 | dependencies: 85 | assertion-error "^1.1.0" 86 | check-error "^1.0.2" 87 | deep-eql "^3.0.1" 88 | get-func-name "^2.0.0" 89 | loupe "^2.3.1" 90 | pathval "^1.1.1" 91 | type-detect "^4.0.5" 92 | 93 | chalk@^4.1.0: 94 | version "4.1.2" 95 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 96 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 97 | dependencies: 98 | ansi-styles "^4.1.0" 99 | supports-color "^7.1.0" 100 | 101 | check-error@^1.0.2: 102 | version "1.0.2" 103 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 104 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 105 | 106 | chokidar@3.5.3: 107 | version "3.5.3" 108 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 109 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 110 | dependencies: 111 | anymatch "~3.1.2" 112 | braces "~3.0.2" 113 | glob-parent "~5.1.2" 114 | is-binary-path "~2.1.0" 115 | is-glob "~4.0.1" 116 | normalize-path "~3.0.0" 117 | readdirp "~3.6.0" 118 | optionalDependencies: 119 | fsevents "~2.3.2" 120 | 121 | cliui@^7.0.2: 122 | version "7.0.4" 123 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 124 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 125 | dependencies: 126 | string-width "^4.2.0" 127 | strip-ansi "^6.0.0" 128 | wrap-ansi "^7.0.0" 129 | 130 | color-convert@^2.0.1: 131 | version "2.0.1" 132 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 133 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 134 | dependencies: 135 | color-name "~1.1.4" 136 | 137 | color-name@~1.1.4: 138 | version "1.1.4" 139 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 140 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 141 | 142 | concat-map@0.0.1: 143 | version "0.0.1" 144 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 145 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 146 | 147 | debug@4.3.3: 148 | version "4.3.3" 149 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" 150 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== 151 | dependencies: 152 | ms "2.1.2" 153 | 154 | decamelize@^4.0.0: 155 | version "4.0.0" 156 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 157 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 158 | 159 | deep-eql@^3.0.1: 160 | version "3.0.1" 161 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 162 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 163 | dependencies: 164 | type-detect "^4.0.0" 165 | 166 | diff@5.0.0: 167 | version "5.0.0" 168 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 169 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 170 | 171 | emoji-regex@^8.0.0: 172 | version "8.0.0" 173 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 174 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 175 | 176 | escalade@^3.1.1: 177 | version "3.1.1" 178 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 179 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 180 | 181 | escape-string-regexp@4.0.0: 182 | version "4.0.0" 183 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 184 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 185 | 186 | fill-range@^7.0.1: 187 | version "7.0.1" 188 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 189 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 190 | dependencies: 191 | to-regex-range "^5.0.1" 192 | 193 | find-up@5.0.0: 194 | version "5.0.0" 195 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 196 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 197 | dependencies: 198 | locate-path "^6.0.0" 199 | path-exists "^4.0.0" 200 | 201 | flat@^5.0.2: 202 | version "5.0.2" 203 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 204 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 205 | 206 | fs.realpath@^1.0.0: 207 | version "1.0.0" 208 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 209 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 210 | 211 | fsevents@~2.3.2: 212 | version "2.3.2" 213 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 214 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 215 | 216 | get-caller-file@^2.0.5: 217 | version "2.0.5" 218 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 219 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 220 | 221 | get-func-name@^2.0.0: 222 | version "2.0.0" 223 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 224 | integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= 225 | 226 | glob-parent@~5.1.2: 227 | version "5.1.2" 228 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 229 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 230 | dependencies: 231 | is-glob "^4.0.1" 232 | 233 | glob@7.2.0: 234 | version "7.2.0" 235 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 236 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 237 | dependencies: 238 | fs.realpath "^1.0.0" 239 | inflight "^1.0.4" 240 | inherits "2" 241 | minimatch "^3.0.4" 242 | once "^1.3.0" 243 | path-is-absolute "^1.0.0" 244 | 245 | growl@1.10.5: 246 | version "1.10.5" 247 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 248 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 249 | 250 | has-flag@^4.0.0: 251 | version "4.0.0" 252 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 253 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 254 | 255 | he@1.2.0: 256 | version "1.2.0" 257 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 258 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 259 | 260 | inflight@^1.0.4: 261 | version "1.0.6" 262 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 263 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 264 | dependencies: 265 | once "^1.3.0" 266 | wrappy "1" 267 | 268 | inherits@2: 269 | version "2.0.4" 270 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 271 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 272 | 273 | is-binary-path@~2.1.0: 274 | version "2.1.0" 275 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 276 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 277 | dependencies: 278 | binary-extensions "^2.0.0" 279 | 280 | is-extglob@^2.1.1: 281 | version "2.1.1" 282 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 283 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 284 | 285 | is-fullwidth-code-point@^3.0.0: 286 | version "3.0.0" 287 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 288 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 289 | 290 | is-glob@^4.0.1, is-glob@~4.0.1: 291 | version "4.0.3" 292 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 293 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 294 | dependencies: 295 | is-extglob "^2.1.1" 296 | 297 | is-number@^7.0.0: 298 | version "7.0.0" 299 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 300 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 301 | 302 | is-plain-obj@^2.1.0: 303 | version "2.1.0" 304 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 305 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 306 | 307 | is-unicode-supported@^0.1.0: 308 | version "0.1.0" 309 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 310 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 311 | 312 | isexe@^2.0.0: 313 | version "2.0.0" 314 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 315 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 316 | 317 | js-yaml@4.1.0: 318 | version "4.1.0" 319 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 320 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 321 | dependencies: 322 | argparse "^2.0.1" 323 | 324 | locate-path@^6.0.0: 325 | version "6.0.0" 326 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 327 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 328 | dependencies: 329 | p-locate "^5.0.0" 330 | 331 | log-symbols@4.1.0: 332 | version "4.1.0" 333 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 334 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 335 | dependencies: 336 | chalk "^4.1.0" 337 | is-unicode-supported "^0.1.0" 338 | 339 | loupe@^2.3.1: 340 | version "2.3.4" 341 | resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" 342 | integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== 343 | dependencies: 344 | get-func-name "^2.0.0" 345 | 346 | minimatch@4.2.1: 347 | version "4.2.1" 348 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" 349 | integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== 350 | dependencies: 351 | brace-expansion "^1.1.7" 352 | 353 | minimatch@^3.0.4: 354 | version "3.1.2" 355 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 356 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 357 | dependencies: 358 | brace-expansion "^1.1.7" 359 | 360 | mocha@^9.2.2: 361 | version "9.2.2" 362 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" 363 | integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== 364 | dependencies: 365 | "@ungap/promise-all-settled" "1.1.2" 366 | ansi-colors "4.1.1" 367 | browser-stdout "1.3.1" 368 | chokidar "3.5.3" 369 | debug "4.3.3" 370 | diff "5.0.0" 371 | escape-string-regexp "4.0.0" 372 | find-up "5.0.0" 373 | glob "7.2.0" 374 | growl "1.10.5" 375 | he "1.2.0" 376 | js-yaml "4.1.0" 377 | log-symbols "4.1.0" 378 | minimatch "4.2.1" 379 | ms "2.1.3" 380 | nanoid "3.3.1" 381 | serialize-javascript "6.0.0" 382 | strip-json-comments "3.1.1" 383 | supports-color "8.1.1" 384 | which "2.0.2" 385 | workerpool "6.2.0" 386 | yargs "16.2.0" 387 | yargs-parser "20.2.4" 388 | yargs-unparser "2.0.0" 389 | 390 | ms@2.1.2: 391 | version "2.1.2" 392 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 393 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 394 | 395 | ms@2.1.3: 396 | version "2.1.3" 397 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 398 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 399 | 400 | nanoid@3.3.1: 401 | version "3.3.1" 402 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" 403 | integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== 404 | 405 | normalize-path@^3.0.0, normalize-path@~3.0.0: 406 | version "3.0.0" 407 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 408 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 409 | 410 | once@^1.3.0: 411 | version "1.4.0" 412 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 413 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 414 | dependencies: 415 | wrappy "1" 416 | 417 | p-limit@^3.0.2: 418 | version "3.1.0" 419 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 420 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 421 | dependencies: 422 | yocto-queue "^0.1.0" 423 | 424 | p-locate@^5.0.0: 425 | version "5.0.0" 426 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 427 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 428 | dependencies: 429 | p-limit "^3.0.2" 430 | 431 | path-exists@^4.0.0: 432 | version "4.0.0" 433 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 434 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 435 | 436 | path-is-absolute@^1.0.0: 437 | version "1.0.1" 438 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 439 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 440 | 441 | pathval@^1.1.1: 442 | version "1.1.1" 443 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 444 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 445 | 446 | picomatch@^2.0.4, picomatch@^2.2.1: 447 | version "2.3.1" 448 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 449 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 450 | 451 | randombytes@^2.1.0: 452 | version "2.1.0" 453 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 454 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 455 | dependencies: 456 | safe-buffer "^5.1.0" 457 | 458 | readdirp@~3.6.0: 459 | version "3.6.0" 460 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 461 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 462 | dependencies: 463 | picomatch "^2.2.1" 464 | 465 | require-directory@^2.1.1: 466 | version "2.1.1" 467 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 468 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 469 | 470 | safe-buffer@^5.1.0: 471 | version "5.2.1" 472 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 473 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 474 | 475 | serialize-javascript@6.0.0: 476 | version "6.0.0" 477 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 478 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 479 | dependencies: 480 | randombytes "^2.1.0" 481 | 482 | string-width@^4.1.0, string-width@^4.2.0: 483 | version "4.2.3" 484 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 485 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 486 | dependencies: 487 | emoji-regex "^8.0.0" 488 | is-fullwidth-code-point "^3.0.0" 489 | strip-ansi "^6.0.1" 490 | 491 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 492 | version "6.0.1" 493 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 494 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 495 | dependencies: 496 | ansi-regex "^5.0.1" 497 | 498 | strip-json-comments@3.1.1: 499 | version "3.1.1" 500 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 501 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 502 | 503 | supports-color@8.1.1: 504 | version "8.1.1" 505 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 506 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 507 | dependencies: 508 | has-flag "^4.0.0" 509 | 510 | supports-color@^7.1.0: 511 | version "7.2.0" 512 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 513 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 514 | dependencies: 515 | has-flag "^4.0.0" 516 | 517 | to-regex-range@^5.0.1: 518 | version "5.0.1" 519 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 520 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 521 | dependencies: 522 | is-number "^7.0.0" 523 | 524 | type-detect@^4.0.0, type-detect@^4.0.5: 525 | version "4.0.8" 526 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 527 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 528 | 529 | which@2.0.2: 530 | version "2.0.2" 531 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 532 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 533 | dependencies: 534 | isexe "^2.0.0" 535 | 536 | workerpool@6.2.0: 537 | version "6.2.0" 538 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" 539 | integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== 540 | 541 | wrap-ansi@^7.0.0: 542 | version "7.0.0" 543 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 544 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 545 | dependencies: 546 | ansi-styles "^4.0.0" 547 | string-width "^4.1.0" 548 | strip-ansi "^6.0.0" 549 | 550 | wrappy@1: 551 | version "1.0.2" 552 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 553 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 554 | 555 | y18n@^5.0.5: 556 | version "5.0.8" 557 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 558 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 559 | 560 | yargs-parser@20.2.4: 561 | version "20.2.4" 562 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 563 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 564 | 565 | yargs-parser@^20.2.2: 566 | version "20.2.9" 567 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 568 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 569 | 570 | yargs-unparser@2.0.0: 571 | version "2.0.0" 572 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 573 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 574 | dependencies: 575 | camelcase "^6.0.0" 576 | decamelize "^4.0.0" 577 | flat "^5.0.2" 578 | is-plain-obj "^2.1.0" 579 | 580 | yargs@16.2.0: 581 | version "16.2.0" 582 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 583 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 584 | dependencies: 585 | cliui "^7.0.2" 586 | escalade "^3.1.1" 587 | get-caller-file "^2.0.5" 588 | require-directory "^2.1.1" 589 | string-width "^4.2.0" 590 | y18n "^5.0.5" 591 | yargs-parser "^20.2.2" 592 | 593 | yocto-queue@^0.1.0: 594 | version "0.1.0" 595 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 596 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 597 | --------------------------------------------------------------------------------