diff --git a/.dependency-cruiser.js b/.dependency-cruiser.js
index 21b641c..78e5afc 100644
--- a/.dependency-cruiser.js
+++ b/.dependency-cruiser.js
@@ -273,11 +273,6 @@ module.exports = {
your webpack config is a function and takes them (see webpack documentation
for details)
*/
- // webpackConfig: {
- // fileName: './webpack.config.js',
- // env: {},
- // arguments: {},
- // },
/* Babel config ('.babelrc', '.babelrc.json', '.babelrc.json5', ...) to use
for compilation (and whatever other naughty things babel plugins do to
diff --git a/.editorconfig b/.editorconfig
index f709510..7396604 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,15 +1,18 @@
# Editor configuration, see http://editorconfig.org
-root = true
-[*]
-charset = utf-8
-end_of_line = lf
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
-[*.md]
+
+root=true # represents the top-level EditorConfig configuration file
+
+[*] # means applicable to all files
+charset = utf-8 #Set the file character set to utf-8
+indent_style = space #Indent style (tab | space)
+indent_size = 2 # indent size
+end_of_line = lf # Control line break type (lf | cr | crlf)
+trim_trailing_whitespace = true # Remove any whitespace characters at the beginning of the line
+insert_final_newline = true #Always insert a new line at the end of the file
+
+[*.md] # Indicates that only md files apply the following rules
max_line_length = off
trim_trailing_whitespace = false
-[*.yml]
+
[*.{yml,yaml}]
indent_size = 2
diff --git a/.eslintrc.js b/.eslintrc.js
index 8a44df5..05afdb4 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,12 +1,17 @@
module.exports = {
+ "parser": "@typescript-eslint/parser",
+ "plugins": [
+ "import",
+ "@typescript-eslint"
+ ],
"extends": [
"plugin:@typescript-eslint/recommended",
"prettier"
],
- ignorePatterns: ["lib/", "dist/", "umd/", "coverage/", "docs/"],
+ "ignorePatterns": ["lib/", "dist/", "umd/", "coverage/", "docs/"],
"rules": {
"import/no-anonymous-default-export": "off",
- "@typescript-eslint/no-unused-vars": "error",
+ "@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
@@ -39,9 +44,6 @@ module.exports = {
}
]
},
- "plugins": [
- "import"
- ],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [
diff --git a/.gitignore b/.gitignore
index d114687..a794ac0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ npm-debug.*
*.orig.*
.DS_Store
.idea
+.vscode
/notes
/backup
diff --git a/.npmignore b/.npmignore
index 59bab7d..5c0a61c 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,4 +1,5 @@
.idea
+.vscode
.auto-changelog
.auto-changelog-template.hbs
.dependency-cruiser.js
@@ -9,7 +10,6 @@
/notes
/backup
-/webpack.config.js
/scripts
/tsconfig.prod.json
diff --git a/.prettierignore b/.prettierignore
index 1938daa..e459c2d 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,5 +1,5 @@
-src/types/data-structures/binary-tree.ts
-src/types/data-structures/bst.ts
-src/types/data-structures/avl-tree.ts
-src/types/data-structures/rb-tree.ts
-src/types/data-structures/tree-multiset.ts
+src/types/data-structures/binary-tree/binary-tree.ts
+src/types/data-structures/binary-tree/bst.ts
+src/types/data-structures/binary-tree/avl-tree.ts
+src/types/data-structures/binary-tree/rb-tree.ts
+src/types/data-structures/binary-tree/tree-multiset.ts
diff --git a/.prettierrc.js b/.prettierrc.js
index 2458204..124f598 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -3,7 +3,7 @@ module.exports = {
"bracketSpacing": false,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
- "bracketSameLine": false,
+ "bracketSameLine": true,
"jsxSingleQuote": true,
"printWidth": 120,
"proseWrap": "preserve",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82c2509..8652626 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,10 +8,18 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
-## [v1.36.5](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
+## [v1.40.0](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes
+- [graph test] edge cases enriched [`#30`](https://github.com/zrwusa/data-structure-typed/pull/30)
+- [graph] Modify the data structure design of the graph to change the g… [`#29`](https://github.com/zrwusa/data-structure-typed/pull/29)
+- Optimization [`#23`](https://github.com/zrwusa/data-structure-typed/pull/23)
+- Optimization [`#20`](https://github.com/zrwusa/data-structure-typed/pull/20)
+- [binary-tree, graph] Replace all code that uses Arrays as makeshift Q… [`#18`](https://github.com/zrwusa/data-structure-typed/pull/18)
+- 1. No need for dfsIterative; integrate it directly into the dfs metho… [`#17`](https://github.com/zrwusa/data-structure-typed/pull/17)
+- [heap] fibonacci heap implemented. [test] big O estimate. [project] n… [`#15`](https://github.com/zrwusa/data-structure-typed/pull/15)
+- [rbtree] implemented, but with bugs [`#13`](https://github.com/zrwusa/data-structure-typed/pull/13)
- [trie] renamed ambiguous methods and add comments to all methods. [`#12`](https://github.com/zrwusa/data-structure-typed/pull/12)
- [binarytree] modified the getDepth method to adhere to the proper def… [`#11`](https://github.com/zrwusa/data-structure-typed/pull/11)
- Trie [`#10`](https://github.com/zrwusa/data-structure-typed/pull/10)
diff --git a/README.md b/README.md
index 7c22027..dc413a5 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ import {
```html
-
+
```
```js
@@ -106,7 +106,7 @@ bst.getDepth(6) === 3; // true
bst.getLeftMost()?.id === 1; // true
-bst.remove(6);
+bst.delete(6);
bst.get(6); // null
bst.isAVLBalanced(); // true
bst.bfs()[0] === 11; // true
@@ -121,7 +121,7 @@ objBST.addMany([{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
{id: 10, keyA: 10}, {id: 5, keyA: 5}]);
-objBST.remove(11);
+objBST.delete(11);
```
#### JS
@@ -142,7 +142,7 @@ bst.getDepth(6) === 3; // true
const leftMost = bst.getLeftMost();
leftMost?.id === 1; // true
expect(leftMost?.id).toBe(1);
-bst.remove(6);
+bst.delete(6);
bst.get(6); // null
bst.isAVLBalanced(); // true or false
const bfsIDs = bst.bfs();
@@ -159,12 +159,12 @@ objBST.addMany([{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
{id: 10, keyA: 10}, {id: 5, keyA: 5}]);
-objBST.remove(11);
+objBST.delete(11);
const avlTree = new AVLTree();
avlTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5])
avlTree.isAVLBalanced(); // true
-avlTree.remove(10);
+avlTree.delete(10);
avlTree.isAVLBalanced(); // true
```
@@ -178,7 +178,7 @@ import {AVLTree} from 'data-structure-typed';
const avlTree = new AVLTree();
avlTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5])
avlTree.isAVLBalanced(); // true
-avlTree.remove(10);
+avlTree.delete(10);
avlTree.isAVLBalanced(); // true
```
@@ -190,7 +190,7 @@ const {AVLTree} = require('data-structure-typed');
const avlTree = new AVLTree();
avlTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5])
avlTree.isAVLBalanced(); // true
-avlTree.remove(10);
+avlTree.delete(10);
avlTree.isAVLBalanced(); // true
```
@@ -214,7 +214,7 @@ graph.addEdge('A', 'B');
graph.hasEdge('A', 'B'); // true
graph.hasEdge('B', 'A'); // false
-graph.removeEdgeSrcToDest('A', 'B');
+graph.deleteEdgeSrcToDest('A', 'B');
graph.hasEdge('A', 'B'); // false
graph.addVertex('C');
@@ -237,7 +237,7 @@ graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
-graph.removeVertex('C');
+graph.deleteVertex('C');
graph.addEdge('A', 'B');
graph.addEdge('B', 'D');
@@ -641,6 +641,14 @@ Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id) // ['A', 'B', 'D
## Code design
+### Adhere to ES6 standard naming conventions for APIs.
+
+Standardize API conventions by using 'add' and 'delete' for element manipulation methods in all data structures.
+
+Opt for concise and clear method names, avoiding excessive length while ensuring explicit intent.
+
+### Object-oriented programming(OOP)
+
By strictly adhering to object-oriented design (BinaryTree -> BST -> AVLTree -> TreeMultiset), you can seamlessly
inherit the existing data structures to implement the customized ones you need. Object-oriented design stands as the
optimal approach to data structure design.
diff --git a/package-lock.json b/package-lock.json
index e055039..8a15adf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
- "version": "1.36.5",
+ "version": "1.40.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
- "version": "1.36.5",
+ "version": "1.40.0",
"license": "MIT",
"devDependencies": {
"@types/benchmark": "^2.1.3",
@@ -15,26 +15,25 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"auto-changelog": "^2.4.0",
- "avl-tree-typed": "^1.36.4",
+ "avl-tree-typed": "^1.39.6",
"benchmark": "^2.1.4",
- "binary-tree-typed": "^1.36.4",
- "bst-typed": "^1.36.4",
+ "binary-tree-typed": "^1.39.6",
+ "bst-typed": "^1.39.6",
"dependency-cruiser": "^14.1.0",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
- "heap-typed": "^1.36.4",
+ "heap-typed": "^1.39.6",
"istanbul-badges-readme": "^1.8.5",
"jest": "^29.7.0",
"prettier": "^3.0.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
+ "tsup": "^7.2.0",
"typedoc": "^0.25.1",
- "typescript": "^5.2.2",
- "webpack": "^5.88.2",
- "webpack-cli": "^5.1.4"
+ "typescript": "^5.2.2"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -678,13 +677,356 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
- "node_modules/@discoveryjs/json-ext": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
- "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": ">=10.0.0"
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
"node_modules/@eslint-community/eslint-utils": {
@@ -703,9 +1045,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz",
- "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==",
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+ "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -757,21 +1099,21 @@
"dev": true
},
"node_modules/@eslint/js": {
- "version": "8.51.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
- "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
+ "version": "8.52.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz",
+ "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.11",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
- "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
+ "version": "0.11.13",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
+ "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
"dev": true,
"dependencies": {
- "@humanwhocodes/object-schema": "^1.2.1",
+ "@humanwhocodes/object-schema": "^2.0.1",
"debug": "^4.1.1",
"minimatch": "^3.0.5"
},
@@ -793,9 +1135,9 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
+ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
"dev": true
},
"node_modules/@istanbuljs/load-nyc-config": {
@@ -1466,6 +1808,7 @@
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
"integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -1478,9 +1821,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.19",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
- "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+ "version": "0.3.20",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
+ "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -1547,9 +1890,9 @@
}
},
"node_modules/@types/babel__core": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz",
- "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==",
+ "version": "7.20.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.3.tgz",
+ "integrity": "sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.20.7",
@@ -1560,18 +1903,18 @@
}
},
"node_modules/@types/babel__generator": {
- "version": "7.6.5",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz",
- "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==",
+ "version": "7.6.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.6.tgz",
+ "integrity": "sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==",
"dev": true,
"dependencies": {
"@babel/types": "^7.0.0"
}
},
"node_modules/@types/babel__template": {
- "version": "7.4.2",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz",
- "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==",
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.3.tgz",
+ "integrity": "sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.1.0",
@@ -1579,83 +1922,86 @@
}
},
"node_modules/@types/babel__traverse": {
- "version": "7.20.2",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz",
- "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==",
+ "version": "7.20.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.3.tgz",
+ "integrity": "sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==",
"dev": true,
"dependencies": {
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/benchmark": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-2.1.3.tgz",
- "integrity": "sha512-psuUawgwIy/hSjO4AUDiPBJhJx72e3cBL+YzmVK/5ofRJC02R0NmvrSenGRuSmJc++0j95y2T01xKKNz50FGZw==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-2.1.4.tgz",
+ "integrity": "sha512-rVCCileCU5NhP9Ix1e03sIn4gd0mpjh7VNULVQAxzF+9vddk6A5QAHzp2h5kXH8pkv1Ow45fUf3QP3wOEiISvA==",
"dev": true
},
"node_modules/@types/eslint": {
- "version": "8.44.4",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.4.tgz",
- "integrity": "sha512-lOzjyfY/D9QR4hY9oblZ76B90MYTB3RrQ4z2vBIJKj9ROCRqdkYl2gSUx1x1a4IWPjKJZLL4Aw1Zfay7eMnmnA==",
+ "version": "8.44.6",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.6.tgz",
+ "integrity": "sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
}
},
"node_modules/@types/eslint-scope": {
- "version": "3.7.5",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz",
- "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==",
+ "version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.6.tgz",
+ "integrity": "sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
}
},
"node_modules/@types/estree": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz",
- "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
- "dev": true
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.3.tgz",
+ "integrity": "sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==",
+ "dev": true,
+ "peer": true
},
"node_modules/@types/graceful-fs": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.7.tgz",
- "integrity": "sha512-MhzcwU8aUygZroVwL2jeYk6JisJrPl/oov/gsgGCue9mkgl9wjGbzReYQClxiUgFDnib9FuHqTndccKeZKxTRw==",
+ "version": "4.1.8",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.8.tgz",
+ "integrity": "sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
- "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+ "integrity": "sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==",
"dev": true
},
"node_modules/@types/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz",
+ "integrity": "sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==",
"dev": true,
"dependencies": {
"@types/istanbul-lib-coverage": "*"
}
},
"node_modules/@types/istanbul-reports": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
- "integrity": "sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz",
+ "integrity": "sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==",
"dev": true,
"dependencies": {
"@types/istanbul-lib-report": "*"
}
},
"node_modules/@types/jest": {
- "version": "29.5.5",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz",
- "integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==",
+ "version": "29.5.6",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.6.tgz",
+ "integrity": "sha512-/t9NnzkOpXb4Nfvg17ieHE6EeSjDS2SGSpNYfoLbUAeL/EOueU/RSdOWFpfQTXBEM7BguYW1XQ0EbM+6RlIh6w==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@@ -1663,9 +2009,9 @@
}
},
"node_modules/@types/json-schema": {
- "version": "7.0.13",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
- "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==",
+ "version": "7.0.14",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
+ "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==",
"dev": true
},
"node_modules/@types/json5": {
@@ -1675,52 +2021,52 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "20.8.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
- "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
+ "version": "20.8.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz",
+ "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==",
"dev": true,
"dependencies": {
- "undici-types": "~5.25.1"
+ "undici-types": "~5.26.4"
}
},
"node_modules/@types/semver": {
- "version": "7.5.3",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz",
- "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==",
"dev": true
},
"node_modules/@types/stack-utils": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
- "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.2.tgz",
+ "integrity": "sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==",
"dev": true
},
"node_modules/@types/yargs": {
- "version": "17.0.28",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.28.tgz",
- "integrity": "sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw==",
+ "version": "17.0.29",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.29.tgz",
+ "integrity": "sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==",
"dev": true,
"dependencies": {
"@types/yargs-parser": "*"
}
},
"node_modules/@types/yargs-parser": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz",
- "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==",
+ "version": "21.0.2",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.2.tgz",
+ "integrity": "sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==",
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz",
- "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.0.tgz",
+ "integrity": "sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "6.7.5",
- "@typescript-eslint/type-utils": "6.7.5",
- "@typescript-eslint/utils": "6.7.5",
- "@typescript-eslint/visitor-keys": "6.7.5",
+ "@typescript-eslint/scope-manager": "6.9.0",
+ "@typescript-eslint/type-utils": "6.9.0",
+ "@typescript-eslint/utils": "6.9.0",
+ "@typescript-eslint/visitor-keys": "6.9.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@@ -1746,15 +2092,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz",
- "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz",
+ "integrity": "sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "6.7.5",
- "@typescript-eslint/types": "6.7.5",
- "@typescript-eslint/typescript-estree": "6.7.5",
- "@typescript-eslint/visitor-keys": "6.7.5",
+ "@typescript-eslint/scope-manager": "6.9.0",
+ "@typescript-eslint/types": "6.9.0",
+ "@typescript-eslint/typescript-estree": "6.9.0",
+ "@typescript-eslint/visitor-keys": "6.9.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1774,13 +2120,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz",
- "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz",
+ "integrity": "sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.7.5",
- "@typescript-eslint/visitor-keys": "6.7.5"
+ "@typescript-eslint/types": "6.9.0",
+ "@typescript-eslint/visitor-keys": "6.9.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1791,13 +2137,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz",
- "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.0.tgz",
+ "integrity": "sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "6.7.5",
- "@typescript-eslint/utils": "6.7.5",
+ "@typescript-eslint/typescript-estree": "6.9.0",
+ "@typescript-eslint/utils": "6.9.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
@@ -1818,9 +2164,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz",
- "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.0.tgz",
+ "integrity": "sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -1831,13 +2177,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz",
- "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz",
+ "integrity": "sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.7.5",
- "@typescript-eslint/visitor-keys": "6.7.5",
+ "@typescript-eslint/types": "6.9.0",
+ "@typescript-eslint/visitor-keys": "6.9.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1858,17 +2204,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz",
- "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.0.tgz",
+ "integrity": "sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.7.5",
- "@typescript-eslint/types": "6.7.5",
- "@typescript-eslint/typescript-estree": "6.7.5",
+ "@typescript-eslint/scope-manager": "6.9.0",
+ "@typescript-eslint/types": "6.9.0",
+ "@typescript-eslint/typescript-estree": "6.9.0",
"semver": "^7.5.4"
},
"engines": {
@@ -1883,12 +2229,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz",
- "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz",
+ "integrity": "sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.7.5",
+ "@typescript-eslint/types": "6.9.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@@ -1899,11 +2245,18 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+ "dev": true
+ },
"node_modules/@webassemblyjs/ast": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
"integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6"
@@ -1913,25 +2266,29 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
"integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
"integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
"integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
"integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.11.6",
"@webassemblyjs/helper-api-error": "1.11.6",
@@ -1942,13 +2299,15 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
"integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
"integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
@@ -1961,6 +2320,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
"integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
"dev": true,
+ "peer": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
@@ -1970,6 +2330,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
"integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
@@ -1978,13 +2339,15 @@
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
"integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
"integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
@@ -2001,6 +2364,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
"integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
@@ -2014,6 +2378,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
"integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-buffer": "1.11.6",
@@ -2026,6 +2391,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
"integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@webassemblyjs/helper-api-error": "1.11.6",
@@ -2040,66 +2406,25 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
"integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
"dev": true,
+ "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
"@xtuc/long": "4.2.2"
}
},
- "node_modules/@webpack-cli/configtest": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
- "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
- "dev": true,
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- }
- },
- "node_modules/@webpack-cli/info": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
- "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
- "dev": true,
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- }
- },
- "node_modules/@webpack-cli/serve": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
- "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
- "dev": true,
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
- },
- "peerDependenciesMeta": {
- "webpack-dev-server": {
- "optional": true
- }
- }
- },
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/acorn": {
"version": "8.10.0",
@@ -2118,6 +2443,7 @@
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"dev": true,
+ "peer": true,
"peerDependencies": {
"acorn": "^8"
}
@@ -2228,6 +2554,12 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true
+ },
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -2396,12 +2728,12 @@
}
},
"node_modules/avl-tree-typed": {
- "version": "1.36.4",
- "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.36.4.tgz",
- "integrity": "sha512-iUTsr9dfxTb4aGBxv93Teh77cCEZBsJpk7MgzvTfUwIgdO3qskj3H8xmgAxzkeRSJqIvfEGC4jil6BNP6NfSBA==",
+ "version": "1.39.6",
+ "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.39.6.tgz",
+ "integrity": "sha512-Yejek2E2+TvXMfCTBjZ9vXYucbOi7sRKo9TJLTvN5FbZ82pnG5MRsik98IvluU0ZY9lEFwu7iFVnPSe2BFdWqQ==",
"dev": true,
"dependencies": {
- "data-structure-typed": "^1.36.4"
+ "data-structure-typed": "^1.39.6"
}
},
"node_modules/babel-jest": {
@@ -2585,13 +2917,22 @@
"platform": "^1.3.3"
}
},
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/binary-tree-typed": {
- "version": "1.36.4",
- "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.36.4.tgz",
- "integrity": "sha512-fDoK2eAm+rdur+oJMBJvyjjjiQ12GpnMmbT+Bgce3tz4wnrQca6sVSEXo1uuAKTIMgDEGeVtsJmD+J6xQLqH/A==",
+ "version": "1.39.6",
+ "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.39.6.tgz",
+ "integrity": "sha512-IkiWRDA+wni3ye5A1l+ogIxfvGflcBKmagU599GIffmkeuLlLVjP2tQyvqpCzEwVRtRO64zEBtL/p30RsNbeew==",
"dev": true,
"dependencies": {
- "data-structure-typed": "^1.36.4"
+ "data-structure-typed": "^1.39.6"
}
},
"node_modules/brace-expansion": {
@@ -2670,12 +3011,12 @@
}
},
"node_modules/bst-typed": {
- "version": "1.36.4",
- "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.36.4.tgz",
- "integrity": "sha512-3soCZc7lJV5ZhC4owO8PLx6VlHrbaFuwOWcpuiQtIDpeVh/mgAHH3M/r/YCiAxLVWXjewerG7TB4T8CBhpo1AA==",
+ "version": "1.39.6",
+ "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.39.6.tgz",
+ "integrity": "sha512-cP9BvJAlEZwLt3lgZFC1PdklD+nzG4ZqxNqEdSxNxvxlbc8RuhlLo6J2bCywnJN+zH/FyDQpM9iBEq07gEixWA==",
"dev": true,
"dependencies": {
- "data-structure-typed": "^1.36.4"
+ "data-structure-typed": "^1.39.6"
}
},
"node_modules/buffer-from": {
@@ -2684,14 +3025,39 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
- "node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "node_modules/bundle-require": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.2.tgz",
+ "integrity": "sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==",
"dev": true,
"dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "load-tsconfig": "^0.2.3"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.17"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
+ "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.1",
+ "set-function-length": "^1.1.1"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2716,9 +3082,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001549",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz",
- "integrity": "sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==",
+ "version": "1.0.30001557",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001557.tgz",
+ "integrity": "sha512-91oR7hLNUP3gG6MLU+n96em322a8Xzes8wWdBKhLgUoiJsAF5irZnxSUCbc+qUZXNnPCfUwLOi9ZCZpkvjQajw==",
"dev": true,
"funding": [
{
@@ -2756,11 +3122,51 @@
"node": ">=10"
}
},
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/chrome-trace-event": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
"integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=6.0"
}
@@ -2870,20 +3276,6 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/clone-deep": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
- "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
- "dev": true,
- "dependencies": {
- "is-plain-object": "^2.0.4",
- "kind-of": "^6.0.2",
- "shallow-clone": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -2915,12 +3307,6 @@
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
- "node_modules/colorette": {
- "version": "2.0.20",
- "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
- "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
- "dev": true
- },
"node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
@@ -3027,9 +3413,9 @@
}
},
"node_modules/data-structure-typed": {
- "version": "1.36.4",
- "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.36.4.tgz",
- "integrity": "sha512-mX+KiaCJ9apd+X7M1dJhtxvUZlV15S36QGawoQhsmhwkHdDsBT06/sGca4vE7I20pZdoX5b34GW+3z4fUJI+/g==",
+ "version": "1.39.6",
+ "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.39.6.tgz",
+ "integrity": "sha512-u9wQfa/7gHiW6Q1SxltLS+EoK8CQwuG7fdcMMrn4FdNgW6rPYfEqy2yNSDlJcbaEZANDQ58cjYLzbjXYQxlQvA==",
"dev": true
},
"node_modules/debug": {
@@ -3110,9 +3496,9 @@
}
},
"node_modules/dependency-cruiser": {
- "version": "14.1.1",
- "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-14.1.1.tgz",
- "integrity": "sha512-npNLWv11pMH9BW4GBLuA5p6KYOXA9UjVDKQ4DzorEhAac5BS1J23K5I2WpEfkJMpwl9PKMsF4T/GDLSq3pogTw==",
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-14.1.2.tgz",
+ "integrity": "sha512-DlHeyF7LxK+pQdEBS+5AykHhUNOyzhek7QCElcmkWfj/dGxuXudT4SrIn6jVtzOnIhU9GAJ8whqm1MHdLDDCHg==",
"dev": true,
"dependencies": {
"acorn": "8.10.0",
@@ -3122,7 +3508,7 @@
"acorn-walk": "8.2.0",
"ajv": "8.12.0",
"chalk": "5.3.0",
- "commander": "11.0.0",
+ "commander": "11.1.0",
"enhanced-resolve": "5.15.0",
"figures": "5.0.0",
"ignore": "5.2.4",
@@ -3155,9 +3541,9 @@
}
},
"node_modules/dependency-cruiser/node_modules/commander": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz",
- "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==",
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"engines": {
"node": ">=16"
@@ -3212,9 +3598,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
- "version": "1.4.554",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.554.tgz",
- "integrity": "sha512-Q0umzPJjfBrrj8unkONTgbKQXzXRrH7sVV7D9ea2yBV3Oaogz991yhbpfvo2LMNkJItmruXTEzVpP9cp7vaIiQ==",
+ "version": "1.4.569",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz",
+ "integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==",
"dev": true
},
"node_modules/emittery": {
@@ -3248,18 +3634,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/envinfo": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz",
- "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==",
- "dev": true,
- "bin": {
- "envinfo": "dist/cli.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -3270,26 +3644,26 @@
}
},
"node_modules/es-abstract": {
- "version": "1.22.2",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",
- "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==",
+ "version": "1.22.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
+ "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==",
"dev": true,
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"arraybuffer.prototype.slice": "^1.0.2",
"available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.5",
"es-set-tostringtag": "^2.0.1",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6",
- "get-intrinsic": "^1.2.1",
+ "get-intrinsic": "^1.2.2",
"get-symbol-description": "^1.0.0",
"globalthis": "^1.0.3",
"gopd": "^1.0.1",
- "has": "^1.0.3",
"has-property-descriptors": "^1.0.0",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
+ "hasown": "^2.0.0",
"internal-slot": "^1.0.5",
"is-array-buffer": "^3.0.2",
"is-callable": "^1.2.7",
@@ -3299,7 +3673,7 @@
"is-string": "^1.0.7",
"is-typed-array": "^1.1.12",
"is-weakref": "^1.0.2",
- "object-inspect": "^1.12.3",
+ "object-inspect": "^1.13.1",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.5.1",
@@ -3313,7 +3687,7 @@
"typed-array-byte-offset": "^1.0.0",
"typed-array-length": "^1.0.4",
"unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.11"
+ "which-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
@@ -3326,29 +3700,30 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz",
"integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/es-set-tostringtag": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
- "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
+ "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.3",
- "has": "^1.0.3",
- "has-tostringtag": "^1.0.0"
+ "get-intrinsic": "^1.2.2",
+ "has-tostringtag": "^1.0.0",
+ "hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-shim-unscopables": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
- "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+ "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
"dev": true,
"dependencies": {
- "has": "^1.0.3"
+ "hasown": "^2.0.0"
}
},
"node_modules/es-to-primitive": {
@@ -3368,6 +3743,43 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
"node_modules/escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -3390,18 +3802,19 @@
}
},
"node_modules/eslint": {
- "version": "8.51.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
- "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
+ "version": "8.52.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz",
+ "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.2",
- "@eslint/js": "8.51.0",
- "@humanwhocodes/config-array": "^0.11.11",
+ "@eslint/js": "8.52.0",
+ "@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -3539,26 +3952,26 @@
}
},
"node_modules/eslint-plugin-import": {
- "version": "2.28.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz",
- "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==",
+ "version": "2.29.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz",
+ "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==",
"dev": true,
"dependencies": {
- "array-includes": "^3.1.6",
- "array.prototype.findlastindex": "^1.2.2",
- "array.prototype.flat": "^1.3.1",
- "array.prototype.flatmap": "^1.3.1",
+ "array-includes": "^3.1.7",
+ "array.prototype.findlastindex": "^1.2.3",
+ "array.prototype.flat": "^1.3.2",
+ "array.prototype.flatmap": "^1.3.2",
"debug": "^3.2.7",
"doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.7",
+ "eslint-import-resolver-node": "^0.3.9",
"eslint-module-utils": "^2.8.0",
- "has": "^1.0.3",
- "is-core-module": "^2.13.0",
+ "hasown": "^2.0.0",
+ "is-core-module": "^2.13.1",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
- "object.fromentries": "^2.0.6",
- "object.groupby": "^1.0.0",
- "object.values": "^1.1.6",
+ "object.fromentries": "^2.0.7",
+ "object.groupby": "^1.0.1",
+ "object.values": "^1.1.7",
"semver": "^6.3.1",
"tsconfig-paths": "^3.14.2"
},
@@ -3775,6 +4188,7 @@
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=0.8.x"
}
@@ -3873,15 +4287,6 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
- "node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
- "dev": true,
- "engines": {
- "node": ">= 4.9.1"
- }
- },
"node_modules/fastq": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
@@ -4072,15 +4477,15 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
- "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
+ "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
"dev": true,
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
+ "function-bind": "^1.1.2",
"has-proto": "^1.0.1",
- "has-symbols": "^1.0.3"
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4171,7 +4576,8 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/global-dirs": {
"version": "3.0.1",
@@ -4283,15 +4689,6 @@
"uglify-js": "^3.1.4"
}
},
- "node_modules/has": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
- "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.4.0"
- }
- },
"node_modules/has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
@@ -4311,12 +4708,12 @@
}
},
"node_modules/has-property-descriptors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
- "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
+ "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.1"
+ "get-intrinsic": "^1.2.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4361,13 +4758,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/heap-typed": {
- "version": "1.36.4",
- "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.36.4.tgz",
- "integrity": "sha512-A5gAttFYkaXXnAjNl7gIyulmoEYB4+usGhsb1QDD2LeHGfe1Pd0wNc/mX5iLFO2feIRcl3hbRw70SQoC+/V3Fg==",
+ "node_modules/hasown": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
+ "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
"dev": true,
"dependencies": {
- "data-structure-typed": "^1.36.4"
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/heap-typed": {
+ "version": "1.39.6",
+ "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.39.6.tgz",
+ "integrity": "sha512-Qi7NbDUnlCS5JSGfemizcJwtFMfGXsSUUZt+h9COTLlGvU4oTQ9t45G60cp4jEywSzXDNUBA/lLkjN8R2uvXJw==",
+ "dev": true,
+ "dependencies": {
+ "data-structure-typed": "^1.39.6"
}
},
"node_modules/html-escaper": {
@@ -4476,13 +4885,13 @@
}
},
"node_modules/internal-slot": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
- "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz",
+ "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.2.0",
- "has": "^1.0.3",
+ "get-intrinsic": "^1.2.2",
+ "hasown": "^2.0.0",
"side-channel": "^1.0.4"
},
"engines": {
@@ -4530,6 +4939,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
@@ -4559,12 +4980,12 @@
}
},
"node_modules/is-core-module": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
- "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+ "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
"dev": true,
"dependencies": {
- "has": "^1.0.3"
+ "hasown": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -4685,18 +5106,6 @@
"node": ">=8"
}
},
- "node_modules/is-plain-object": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "dev": true,
- "dependencies": {
- "isobject": "^3.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -4818,15 +5227,6 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
- "node_modules/isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/istanbul-badges-readme": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/istanbul-badges-readme/-/istanbul-badges-readme-1.8.5.tgz",
@@ -6143,6 +6543,15 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/joycon": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6224,15 +6633,6 @@
"json-buffer": "3.0.1"
}
},
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@@ -6264,17 +6664,36 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
+ "node_modules/load-tsconfig": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
+ "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=6.11.5"
}
@@ -6312,6 +6731,12 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -6402,6 +6827,7 @@
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">= 0.6"
}
@@ -6411,6 +6837,7 @@
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
+ "peer": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -6454,6 +6881,17 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -6519,10 +6957,19 @@
"node": ">=8"
}
},
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-inspect": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.0.tgz",
- "integrity": "sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==",
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
+ "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -6862,6 +7309,35 @@
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
"dev": true
},
+ "node_modules/postcss-load-config": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
+ "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
+ "dev": true,
+ "dependencies": {
+ "lilconfig": "^2.0.5",
+ "yaml": "^2.1.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -6963,6 +7439,7 @@
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -6973,6 +7450,18 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
@@ -7119,6 +7608,22 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/rollup": {
+ "version": "3.29.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+ "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -7178,7 +7683,8 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "peer": true
},
"node_modules/safe-regex": {
"version": "2.1.1",
@@ -7208,6 +7714,7 @@
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
@@ -7226,6 +7733,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -7242,6 +7750,7 @@
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true,
+ "peer": true,
"peerDependencies": {
"ajv": "^6.9.1"
}
@@ -7250,7 +7759,8 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/semver": {
"version": "7.5.4",
@@ -7302,10 +7812,26 @@
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
"integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
"dev": true,
+ "peer": true,
"dependencies": {
"randombytes": "^2.1.0"
}
},
+ "node_modules/set-function-length": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
+ "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
+ "dev": true,
+ "dependencies": {
+ "define-data-property": "^1.1.1",
+ "get-intrinsic": "^1.2.1",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/set-function-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
@@ -7320,18 +7846,6 @@
"node": ">= 0.4"
}
},
- "node_modules/shallow-clone": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
- "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -7590,6 +8104,57 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/sucrase": {
+ "version": "3.34.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
+ "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "7.1.6",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sucrase/node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/sucrase/node_modules/glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7630,10 +8195,11 @@
"dev": true
},
"node_modules/terser": {
- "version": "5.21.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz",
- "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==",
+ "version": "5.22.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.22.0.tgz",
+ "integrity": "sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==",
"dev": true,
+ "peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -7652,6 +8218,7 @@
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
"integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
"dev": true,
+ "peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
@@ -7686,6 +8253,7 @@
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -7700,6 +8268,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
+ "peer": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -7714,13 +8283,15 @@
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "dev": true,
+ "peer": true
},
"node_modules/terser/node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
+ "peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -7746,6 +8317,27 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@@ -7779,6 +8371,15 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true
},
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
"node_modules/ts-api-utils": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
@@ -7791,6 +8392,12 @@
"typescript": ">=4.2.0"
}
},
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true
+ },
"node_modules/ts-jest": {
"version": "29.1.1",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz",
@@ -8031,6 +8638,98 @@
"node": ">=4"
}
},
+ "node_modules/tsup": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/tsup/-/tsup-7.2.0.tgz",
+ "integrity": "sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==",
+ "dev": true,
+ "dependencies": {
+ "bundle-require": "^4.0.0",
+ "cac": "^6.7.12",
+ "chokidar": "^3.5.1",
+ "debug": "^4.3.1",
+ "esbuild": "^0.18.2",
+ "execa": "^5.0.0",
+ "globby": "^11.0.3",
+ "joycon": "^3.0.1",
+ "postcss-load-config": "^4.0.1",
+ "resolve-from": "^5.0.0",
+ "rollup": "^3.2.5",
+ "source-map": "0.8.0-beta.0",
+ "sucrase": "^3.20.3",
+ "tree-kill": "^1.2.2"
+ },
+ "bin": {
+ "tsup": "dist/cli-default.js",
+ "tsup-node": "dist/cli-node.js"
+ },
+ "engines": {
+ "node": ">=16.14"
+ },
+ "peerDependencies": {
+ "@swc/core": "^1",
+ "postcss": "^8.4.12",
+ "typescript": ">=4.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsup/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tsup/node_modules/source-map": {
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/tsup/node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/tsup/node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ },
+ "node_modules/tsup/node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -8216,9 +8915,9 @@
}
},
"node_modules/undici-types": {
- "version": "5.25.3",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
- "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
},
"node_modules/update-browserslist-db": {
@@ -8300,6 +8999,7 @@
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
"dev": true,
+ "peer": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -8331,6 +9031,7 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
"integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.0",
@@ -8373,78 +9074,12 @@
}
}
},
- "node_modules/webpack-cli": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
- "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
- "dev": true,
- "dependencies": {
- "@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.1.1",
- "@webpack-cli/info": "^2.0.2",
- "@webpack-cli/serve": "^2.0.5",
- "colorette": "^2.0.14",
- "commander": "^10.0.1",
- "cross-spawn": "^7.0.3",
- "envinfo": "^7.7.3",
- "fastest-levenshtein": "^1.0.12",
- "import-local": "^3.0.2",
- "interpret": "^3.1.1",
- "rechoir": "^0.8.0",
- "webpack-merge": "^5.7.3"
- },
- "bin": {
- "webpack-cli": "bin/cli.js"
- },
- "engines": {
- "node": ">=14.15.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- },
- "peerDependencies": {
- "webpack": "5.x.x"
- },
- "peerDependenciesMeta": {
- "@webpack-cli/generators": {
- "optional": true
- },
- "webpack-bundle-analyzer": {
- "optional": true
- },
- "webpack-dev-server": {
- "optional": true
- }
- }
- },
- "node_modules/webpack-cli/node_modules/commander": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
- "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
- "dev": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/webpack-merge": {
- "version": "5.9.0",
- "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz",
- "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==",
- "dev": true,
- "dependencies": {
- "clone-deep": "^4.0.1",
- "wildcard": "^2.0.0"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
"node_modules/webpack-sources": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=10.13.0"
}
@@ -8454,6 +9089,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
+ "peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -8467,6 +9103,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=4.0"
}
@@ -8513,13 +9150,13 @@
}
},
"node_modules/which-typed-array": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
- "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
+ "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
"dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.4",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0"
@@ -8531,12 +9168,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/wildcard": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
- "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
- "dev": true
- },
"node_modules/wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
@@ -8633,6 +9264,15 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
},
+ "node_modules/yaml": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz",
+ "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index 292e221..11aed58 100644
--- a/package.json
+++ b/package.json
@@ -1,22 +1,25 @@
{
"name": "data-structure-typed",
- "version": "1.36.6",
+ "version": "1.40.0",
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
- "main": "dist/index.js",
- "module": "lib/index.js",
- "types": "lib/index.d.ts",
- "source": "src/index.ts",
- "umd:main": "umd/bundle.min.js",
+ "main": "dist/cjs/index.js",
+ "module": "dist/mjs/index.js",
+ "types": "dist/mjs/index.d.ts",
+ "umd:main": "dist/umd/data-structure-typed.min.js",
"exports": {
- "import": "./lib/index.js",
- "require": "./dist/index.js"
+ ".": {
+ "import": "./dist/mjs/index.js",
+ "require": "./dist/cjs/index.js",
+ "types": "./dist/mjs/index.d.ts"
+ }
},
"scripts": {
- "build": "npm run build:es6 && npm run build:commonjs && npm run build:umd && npm run build:docs",
- "build:es6": "rm -rf lib && tsc",
- "build:commonjs": "rm -rf dist && tsc --project tsconfig.prod.json",
- "build:umd": "webpack",
+ "build": "npm run build:mjs && npm run build:cjs && npm run build:umd && npm run build:docs",
+ "build:mjs": "rm -rf dist/mjs && tsc -p tsconfig.json",
+ "build:cjs": "rm -rf dist/cjs && tsc -p tsconfig-cjs.json",
+ "build:umd": "tsup",
"build:docs": "typedoc --out docs ./src",
+ "check": "tsc --noEmit",
"lint:src": "eslint --fix 'src/**/*.{js,ts}'",
"lint:test": "eslint --fix 'test/**/*.{js,ts}'",
"lint": "npm run lint:src && npm run lint:test",
@@ -26,13 +29,17 @@
"fix:src": "npm run lint:src && npm run format:src",
"fix:test": "npm run lint:test && npm run format:test",
"fix": "npm run fix:src && npm run fix:test",
- "update:individuals": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed --save-dev",
- "install:individuals": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed queue-typed --save-dev",
+ "update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed --save-dev",
+ "install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed queue-typed --save-dev",
"test": "jest",
"check:deps": "dependency-cruiser src",
"changelog": "auto-changelog",
"coverage:badge": "istanbul-badges-readme",
- "ci": "env && npm run lint && npm run build && npm run update:individuals && npm run test && git fetch --tags && npm run changelog"
+ "ci": "env && git fetch --tags && npm run lint && npm run build && npm run update:subs && npm run test && npm run changelog",
+ "copy:to-subs": "sh scripts/copy_to_all_subs.sh",
+ "publish:subs": "npm run copy:to-subs && sh scripts/publish_all_subs.sh",
+ "publish:docs": "sh scripts/publish_docs.sh",
+ "publish:all": "npm run ci && npm publish && npm run publish:docs && npm run publish:subs"
},
"repository": {
"type": "git",
@@ -54,26 +61,25 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"auto-changelog": "^2.4.0",
- "avl-tree-typed": "^1.36.4",
+ "avl-tree-typed": "^1.39.6",
"benchmark": "^2.1.4",
- "binary-tree-typed": "^1.36.4",
- "bst-typed": "^1.36.4",
+ "binary-tree-typed": "^1.39.6",
+ "bst-typed": "^1.39.6",
"dependency-cruiser": "^14.1.0",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
- "heap-typed": "^1.36.4",
+ "heap-typed": "^1.39.6",
"istanbul-badges-readme": "^1.8.5",
"jest": "^29.7.0",
"prettier": "^3.0.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
+ "tsup": "^7.2.0",
"typedoc": "^0.25.1",
- "typescript": "^5.2.2",
- "webpack": "^5.88.2",
- "webpack-cli": "^5.1.4"
+ "typescript": "^5.2.2"
},
"keywords": [
"data",
diff --git a/scripts/config.json b/scripts/config.json
new file mode 100644
index 0000000..06383c9
--- /dev/null
+++ b/scripts/config.json
@@ -0,0 +1,5 @@
+{
+ "sourceDir": "/Users/revone/projects/data-structure-typed",
+ "individualsDir": "/Users/revone/projects/data-structure-typed-individuals",
+ "docsDir": "/Users/revone/projects/data-structure-typed-docs"
+}
diff --git a/scripts/copy_to_all_subs.sh b/scripts/copy_to_all_subs.sh
new file mode 100644
index 0000000..a12a000
--- /dev/null
+++ b/scripts/copy_to_all_subs.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Enable extended globbing
+shopt -s extglob
+
+# target directory
+individuals_dir_default=$(jq -r .individualsDir ./scripts/config.json)
+
+# Source directory
+source_dir_default=$(jq -r .sourceDir ./scripts/config.json)
+
+# List of directories
+directories=(
+ "avl-tree-typed"
+ "binary-tree-typed"
+ "bst-typed"
+ "deque-typed"
+ "directed-graph-typed"
+ "doubly-linked-list-typed"
+ "graph-typed"
+ "heap-typed"
+ "linked-list-typed"
+ "max-heap-typed"
+ "max-priority-queue-typed"
+ "min-heap-typed"
+ "min-priority-queue-typed"
+ "priority-queue-typed"
+ "singly-linked-list-typed"
+ "queue-typed"
+ "stack-typed"
+ "tree-multiset-typed"
+ "trie-typed"
+ "undirected-graph-typed"
+)
+
+# Loop through each directory
+for dir in "${directories[@]}"; do
+ # Delete all files except index.ts
+ find "$individuals_dir_default"/"$dir"/src -type f ! -name 'index.ts' -delete
+
+ # Copy the files to the target directory, excluding index.ts
+ cp -R "$source_dir_default"/src/!(index.ts) "$individuals_dir_default"/"$dir"/src
+done
+
+echo "All packages copied."
diff --git a/scripts/publish_all_subs.sh b/scripts/publish_all_subs.sh
index 8ea802d..7b7da2f 100755
--- a/scripts/publish_all_subs.sh
+++ b/scripts/publish_all_subs.sh
@@ -1,5 +1,10 @@
#!/bin/bash
+# Read the version variable from config.json
+source_dir_default=$(jq -r .sourceDir ./scripts/config.json)
+
+individuals_dir_default=$(jq -r .individualsDir ./scripts/config.json)
+
# Function to prompt for a directory path with a default value
prompt_for_directory() {
local message="$1"
@@ -9,10 +14,12 @@ prompt_for_directory() {
}
# Prompt for the source directory path
-source_dir=$(prompt_for_directory "Enter the source directory" "/Users/revone/projects/data-structure-typed")
+#source_dir=$(prompt_for_directory "Enter the source directory" "$source_dir_default")
+source_dir="$source_dir_default"
# Prompt for the destination directory path
-individuals_dir=$(prompt_for_directory "Enter the destination directory" "/Users/revone/projects/data-structure-typed-individuals")
+#individuals_dir=$(prompt_for_directory "Enter the destination directory" "$individuals_dir_default")
+individuals_dir="$individuals_dir_default"
# Read the version variable from package.json
diff --git a/scripts/publish_docs.sh b/scripts/publish_docs.sh
index 414b02b..71b1853 100755
--- a/scripts/publish_docs.sh
+++ b/scripts/publish_docs.sh
@@ -1,5 +1,11 @@
#!/bin/bash
+
+# Read the version variable from config.json
+source_dir_default=$(jq -r .sourceDir ./scripts/config.json)
+
+docs_dir_default=$(jq -r .docsDir ./scripts/config.json)
+
# Function to prompt for a directory path with a default value
prompt_for_directory() {
local message="$1"
@@ -9,10 +15,12 @@ prompt_for_directory() {
}
# Prompt for the source directory path
-source_dir=$(prompt_for_directory "Enter the source directory" "/Users/revone/projects/data-structure-typed")
+#source_dir=$(prompt_for_directory "Enter the source directory" "$source_dir_default")
+source_dir="$source_dir_default"
-# Prompt for the destination directory path
-docs_dir=$(prompt_for_directory "Enter the destination directory" "/Users/revone/projects/data-structure-typed-docs")
+# Prompt for the docs directory path
+#docs_dir=$(prompt_for_directory "Enter the docs directory" "$docs_dir_default")
+docs_dir="$docs_dir_default"
# Check if jq is installed and install it if needed
if ! command -v jq &> /dev/null; then
diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts
index 32cb1d1..d98a67c 100644
--- a/src/data-structures/binary-tree/avl-tree.ts
+++ b/src/data-structures/binary-tree/avl-tree.ts
@@ -6,22 +6,22 @@
* @license MIT License
*/
import {BST, BSTNode} from './bst';
-import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeKey} from '../../types';
+import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BTNKey} from '../../types';
+import {BTNCallback} from '../../types';
import {IBinaryTree} from '../../interfaces';
-export class AVLTreeNode = AVLTreeNodeNested> extends BSTNode<
- V,
- FAMILY
-> {
+export class AVLTreeNode = AVLTreeNodeNested> extends BSTNode {
height: number;
- constructor(key: BinaryTreeNodeKey, val?: V) {
- super(key, val);
+ constructor(key: BTNKey, value?: V) {
+ super(key, value);
this.height = 0;
}
}
-export class AVLTree = AVLTreeNode> extends BST implements IBinaryTree {
+export class AVLTree = AVLTreeNode>>
+ extends BST
+ implements IBinaryTree {
/**
* This is a constructor function for an AVL tree data structure in TypeScript.
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
@@ -33,66 +33,51 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The `swapLocation` function swaps the location of two nodes in a binary tree.
- * @param {N} srcNode - The source node that you want to swap with the destination node.
- * @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
- * be swapped to.
- * @returns The `destNode` is being returned.
- */
- override swapLocation(srcNode: N, destNode: N): N {
- const {key, val, height} = destNode;
- const tempNode = this.createNode(key, val);
-
- if (tempNode) {
- tempNode.height = height;
-
- destNode.key = srcNode.key;
- destNode.val = srcNode.val;
- destNode.height = srcNode.height;
-
- srcNode.key = tempNode.key;
- srcNode.val = tempNode.val;
- srcNode.height = tempNode.height;
- }
-
- return destNode;
- }
-
- /**
- * The function creates a new AVL tree node with the given key and value.
- * @param {BinaryTreeNodeKey} key - The `key` parameter is the identifier for the binary tree node. It is used to uniquely
- * identify each node in the tree.
- * @param [val] - The `val` parameter is an optional value that can be assigned to the node. It represents the value
- * that will be stored in the node.
+ * The function creates a new AVL tree node with the specified key and value.
+ * @param {BTNKey} key - The key parameter is the key value that will be associated with
+ * the new node. It is used to determine the position of the node in the binary search tree.
+ * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It is of
+ * type `V`, which means it can be any value that is assignable to the `value` property of the
+ * node type `N`.
* @returns a new AVLTreeNode object with the specified key and value.
*/
- override createNode(key: BinaryTreeNodeKey, val?: N['val']): N {
- return new AVLTreeNode(key, val) as N;
+ override createNode(key: BTNKey, value?: V): N {
+ return new AVLTreeNode(key, value) as N;
}
/**
- * The function overrides the add method of a binary tree node and balances the tree after inserting a new node.
- * @param {BinaryTreeNodeKey} key - The `key` parameter is the identifier of the binary tree node that we want to add.
- * @param [val] - The `val` parameter is an optional value that can be assigned to the node being added. It is of type
- * `N['val']`, which means it should be of the same type as the `val` property of the nodes in the binary tree.
- * @returns The method is returning the inserted node, or null or undefined if the insertion was not successful.
+ * The function overrides the add method of a binary tree node and balances the tree after inserting
+ * a new node.
+ * @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can accept either a
+ * `BTNKey` or a `N` (which represents a node in the binary tree) or `null`.
+ * @param [value] - The `value` parameter is the value that you want to assign to the new node that you
+ * are adding to the binary search tree.
+ * @returns The method is returning the inserted node (`N`), `null`, or `undefined`.
*/
- override add(key: BinaryTreeNodeKey, val?: N['val']): N | null | undefined {
- // TODO support node as a param
- const inserted = super.add(key, val);
+ override add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
+ const inserted = super.add(keyOrNode, value);
if (inserted) this._balancePath(inserted);
return inserted;
}
/**
- * The function overrides the remove method of a binary tree and performs additional operations to balance the tree after
- * deletion.
- * @param {BinaryTreeNodeKey} key - The `key` parameter represents the identifier of the binary tree node that needs to be
- * removed.
+ * The function overrides the delete method of a binary tree and balances the tree after deleting a
+ * node if necessary.
+ * @param {ReturnType} identifier - The `identifier` parameter is either a
+ * `BTNKey` or a generic type `N`. It represents the property of the node that we are
+ * searching for. It can be a specific key value or any other property of the node.
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
+ * included in the result. The `callback` parameter has a default value of
+ * `((node: N) => node.key)`
* @returns The method is returning an array of `BinaryTreeDeletedResult` objects.
*/
- override remove(key: BinaryTreeNodeKey): BinaryTreeDeletedResult[] {
- const deletedResults = super.remove(key);
+ override delete>(
+ identifier: ReturnType,
+ callback: C = ((node: N) => node.key) as C
+ ): BinaryTreeDeletedResult[] {
+ if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
+ const deletedResults = super.delete(identifier, callback);
for (const {needBalanced} of deletedResults) {
if (needBalanced) {
this._balancePath(needBalanced);
@@ -102,10 +87,37 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The balance factor of a given AVL tree node is calculated by subtracting the height of its left subtree from the
- * height of its right subtree.
- * @param node - The parameter "node" is of type N, which represents a node in an AVL tree.
- * @returns The balance factor of the given AVL tree node.
+ * The function swaps the key, value, and height properties between two nodes in a binary tree.
+ * @param {N} srcNode - The `srcNode` parameter represents the source node that needs to be swapped
+ * with the `destNode`.
+ * @param {N} destNode - The `destNode` parameter represents the destination node where the values
+ * from the source node (`srcNode`) will be swapped to.
+ * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.
+ */
+ protected override _swap(srcNode: N, destNode: N): N {
+ const {key, value, height} = destNode;
+ const tempNode = this.createNode(key, value);
+
+ if (tempNode) {
+ tempNode.height = height;
+
+ destNode.key = srcNode.key;
+ destNode.value = srcNode.value;
+ destNode.height = srcNode.height;
+
+ srcNode.key = tempNode.key;
+ srcNode.value = tempNode.value;
+ srcNode.height = tempNode.height;
+ }
+
+ return destNode;
+ }
+
+ /**
+ * The function calculates the balance factor of a node in a binary tree.
+ * @param {N} node - The parameter "node" represents a node in a binary tree data structure.
+ * @returns the balance factor of a given node. The balance factor is calculated by subtracting the
+ * height of the left subtree from the height of the right subtree.
*/
protected _balanceFactor(node: N): number {
if (!node.right)
@@ -118,8 +130,9 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The function updates the height of a node in an AVL tree based on the heights of its left and right subtrees.
- * @param node - The parameter `node` is an AVLTreeNode object, which represents a node in an AVL tree.
+ * The function updates the height of a node in a binary tree based on the heights of its left and
+ * right children.
+ * @param {N} node - The parameter "node" represents a node in a binary tree data structure.
*/
protected _updateHeight(node: N): void {
if (!node.left && !node.right) node.height = 0;
@@ -131,9 +144,10 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The `_balancePath` function balances the AVL tree by performing appropriate rotations based on the balance factor of
- * each node in the path from the given node to the root.
- * @param node - The `node` parameter is an AVLTreeNode object, which represents a node in an AVL tree.
+ * The `_balancePath` function is used to update the heights of nodes and perform rotation operations
+ * to restore balance in an AVL tree after inserting a node.
+ * @param {N} node - The `node` parameter in the `_balancePath` function represents the node in the
+ * AVL tree that needs to be balanced.
*/
protected _balancePath(node: N): void {
const path = this.getPathToRoot(node, false); // first O(log n) + O(log n)
@@ -146,7 +160,7 @@ export class AVLTree = AVLTreeNode> extends B
// Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:
switch (
this._balanceFactor(A) // second O(1)
- ) {
+ ) {
case -2:
if (A && A.left) {
if (this._balanceFactor(A.left) <= 0) {
@@ -175,8 +189,8 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The `_balanceLL` function performs a left-left rotation on an AVL tree to balance it.
- * @param A - The parameter A is an AVLTreeNode object.
+ * The function `_balanceLL` performs a left-left rotation to balance a binary tree.
+ * @param {N} A - A is a node in a binary tree.
*/
protected _balanceLL(A: N): void {
const parentOfA = A.parent;
@@ -205,8 +219,8 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The `_balanceLR` function performs a left-right rotation to balance an AVL tree.
- * @param A - A is an AVLTreeNode object.
+ * The `_balanceLR` function performs a left-right rotation to balance a binary tree.
+ * @param {N} A - A is a node in a binary tree.
*/
protected _balanceLR(A: N): void {
const parentOfA = A.parent;
@@ -253,8 +267,8 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The `_balanceRR` function performs a right-right rotation on an AVL tree to balance it.
- * @param A - The parameter A is an AVLTreeNode object.
+ * The function `_balanceRR` performs a right-right rotation to balance a binary tree.
+ * @param {N} A - A is a node in a binary tree.
*/
protected _balanceRR(A: N): void {
const parentOfA = A.parent;
@@ -288,8 +302,8 @@ export class AVLTree = AVLTreeNode> extends B
}
/**
- * The `_balanceRL` function performs a right-left rotation to balance an AVL tree.
- * @param A - A is an AVLTreeNode object.
+ * The function `_balanceRL` performs a right-left rotation to balance a binary tree.
+ * @param {N} A - A is a node in a binary tree.
*/
protected _balanceRL(A: N): void {
const parentOfA = A.parent;
diff --git a/src/data-structures/binary-tree/binary-indexed-tree.ts b/src/data-structures/binary-tree/binary-indexed-tree.ts
index b83b265..07d8546 100644
--- a/src/data-structures/binary-tree/binary-indexed-tree.ts
+++ b/src/data-structures/binary-tree/binary-indexed-tree.ts
@@ -5,40 +5,130 @@
* @copyright Copyright (c) 2022 Tyler Zeng
* @license MIT License
*/
+import {getMSB} from '../../utils';
+
export class BinaryIndexedTree {
+ protected readonly _freq: number;
+ protected readonly _max: number;
+
/**
- * The constructor initializes an array with a specified length and fills it with zeros.
- * @param {number} n - The parameter `n` represents the size of the array that will be used to store the sum tree. The
- * sum tree is a binary tree data structure used to efficiently calculate the sum of a range of elements in an array.
- * The size of the sum tree array is `n + 1` because
+ * The constructor initializes the properties of an object, including default frequency, maximum
+ * value, a freqMap data structure, the most significant bit, and the count of negative frequencies.
+ * @param - - `frequency`: The default frequency value. It is optional and has a default
+ * value of 0.
*/
- constructor(n: number) {
- this._sumTree = new Array(n + 1).fill(0);
+ constructor({frequency = 0, max}: { frequency?: number; max: number }) {
+ this._freq = frequency;
+ this._max = max;
+ this._freqMap = {0: 0};
+ this._msb = getMSB(max);
+ this._negativeCount = frequency < 0 ? max : 0;
}
- private _sumTree: number[];
+ protected _freqMap: Record;
- get sumTree(): number[] {
- return this._sumTree;
+ get freqMap(): Record {
+ return this._freqMap;
}
- static lowBit(x: number) {
- return x & -x;
+ protected _msb: number;
+
+ get msb(): number {
+ return this._msb;
+ }
+
+ protected _negativeCount: number;
+
+ get negativeCount(): number {
+ return this._negativeCount;
+ }
+
+ get freq(): number {
+ return this._freq;
+ }
+
+ get max(): number {
+ return this._max;
}
/**
- * The update function updates the values in a binary indexed tree by adding a delta value to the specified index and
- * its ancestors.
- * @param {number} i - The parameter `i` represents the index of the element in the `_sumTree` array that needs to be
- * updated.
- * @param {number} delta - The "delta" parameter represents the change in value that needs to be added to the element
- * at index "i" in the "_sumTree" array.
+ * The function "readSingle" reads a single number from a specified index.
+ * @param {number} index - The `index` parameter is a number that represents the index of an element in a
+ * collection or array.
+ * @returns a number.
*/
- update(i: number, delta: number) {
- while (i < this._sumTree.length) {
- this._sumTree[i] += delta;
- i += BinaryIndexedTree.lowBit(i);
+ readSingle(index: number): number {
+ this._checkIndex(index);
+ return this._readSingle(index);
+ }
+
+ /**
+ * The "update" function updates the value at a given index by adding a delta and triggers a callback
+ * to notify of the change.
+ * @param {number} position - The `index` parameter represents the index of the element that needs to be
+ * updated in the data structure.
+ * @param {number} change - The "delta" parameter represents the change in value that needs to be
+ * applied to the frequency at the specified index.
+ */
+ update(position: number, change: number): void {
+ this._checkIndex(position);
+ const freqCur = this._readSingle(position);
+
+ this._update(position, change);
+ this._updateNegativeCount(freqCur, freqCur + change);
+ }
+
+ /**
+ * The function "writeSingle" checks the index and writes a single value with a given frequency.
+ * @param {number} index - The `index` parameter is a number that represents the index of an element. It
+ * is used to identify the specific element that needs to be written.
+ * @param {number} freq - The `freq` parameter represents the frequency value that needs to be
+ * written.
+ */
+ writeSingle(index: number, freq: number): void {
+ this._checkIndex(index);
+ this._writeSingle(index, freq);
+ }
+
+ /**
+ * The read function takes a count parameter, checks if it is an integer, and returns the result of
+ * calling the _read function with the count parameter clamped between 0 and the maximum value.
+ * @param {number} count - The `count` parameter is a number that represents the number of items to
+ * read.
+ * @returns a number.
+ */
+ read(count: number): number {
+ if (!Number.isInteger(count)) {
+ throw new Error('Invalid count');
}
+ return this._read(Math.max(Math.min(count, this.max), 0));
+ }
+
+ /**
+ * The function returns the lower bound of a non-descending sequence that sums up to a given number.
+ * @param {number} sum - The `sum` parameter is a number that represents the target sum that we want
+ * to find in the sequence.
+ * @returns The lowerBound function is returning a number.
+ */
+ lowerBound(sum: number): number {
+ if (this.negativeCount > 0) {
+ throw new Error('Sequence is not non-descending');
+ }
+ return this._binarySearch(sum, (x, y) => x < y);
+ }
+
+ /**
+ * The upperBound function returns the index of the first element in a sequence that is greater than
+ * or equal to a given sum.
+ * @param {number} sum - The "sum" parameter is a number that represents the target sum that we want
+ * to find in the sequence.
+ * @returns The upperBound function is returning a number.
+ */
+ upperBound(sum: number): number {
+ if (this.negativeCount > 0) {
+ throw new Error('Must not be descending');
+ }
+ return this._binarySearch(sum, (x, y) => x <= y);
}
/**
@@ -48,29 +138,169 @@ export class BinaryIndexedTree {
* @returns The function `getPrefixSum` returns the prefix sum of the elements in the binary indexed tree up to index
* `i`.
*/
- getPrefixSum(i: number) {
+ getPrefixSum(i: number): number {
+ this._checkIndex(i);
+ i++; // Convert to 1-based index
+
let sum = 0;
while (i > 0) {
- sum += this._sumTree[i];
- i -= BinaryIndexedTree.lowBit(i);
+ sum += this._getFrequency(i);
+ i -= i & -i;
}
+
return sum;
}
/**
- * The function `getRangeSum` calculates the sum of a range of numbers in an array.
- * @param {number} start - The start parameter is the starting index of the range for which we want to calculate the
- * sum.
- * @param {number} end - The "end" parameter represents the ending index of the range for which we want to calculate
- * the sum.
- * @returns the sum of the elements in the range specified by the start and end indices.
+ * The function returns the value of a specific index in a freqMap data structure, or a default value if
+ * the index is not found.
+ * @param {number} index - The `index` parameter is a number that represents the index of a node in a
+ * freqMap data structure.
+ * @returns a number.
*/
- getRangeSum(start: number, end: number): number {
- if (!(0 <= start && start <= end && end <= this._sumTree.length)) throw 'Index out of bounds';
- return this.getPrefixSum(end) - this.getPrefixSum(start);
+ protected _getFrequency(index: number): number {
+ if (index in this.freqMap) {
+ return this.freqMap[index];
+ }
+
+ return this.freq * (index & -index);
}
- protected _setSumTree(value: number[]) {
- this._sumTree = value;
+ /**
+ * The function _updateFrequency adds a delta value to the element at the specified index in the freqMap array.
+ * @param {number} index - The index parameter is a number that represents the index of the freqMap
+ * element that needs to be updated.
+ * @param {number} delta - The `delta` parameter represents the change in value that needs to be
+ * added to the freqMap at the specified `index`.
+ */
+ protected _updateFrequency(index: number, delta: number): void {
+ this.freqMap[index] = this._getFrequency(index) + delta;
+ }
+
+ /**
+ * The function checks if the given index is valid and within the range.
+ * @param {number} index - The parameter "index" is of type number and represents the index value
+ * that needs to be checked.
+ */
+ protected _checkIndex(index: number): void {
+ if (!Number.isInteger(index)) {
+ throw new Error('Invalid index: Index must be an integer.');
+ }
+ if (index < 0 || index >= this.max) {
+ throw new Error('Index out of range: Index must be within the range [0, this.max).');
+ }
+ }
+
+ /**
+ * The function calculates the sum of elements in an array up to a given index using a binary indexed
+ * freqMap.
+ * @param {number} index - The `index` parameter is a number that represents the index of an element in a
+ * data structure.
+ * @returns a number.
+ */
+ protected _readSingle(index: number): number {
+ index = index + 1;
+ let sum = this._getFrequency(index);
+ const z = index - (index & -index);
+
+ index--;
+
+ while (index !== z) {
+ sum -= this._getFrequency(index);
+ index -= index & -index;
+ }
+
+ return sum;
+ }
+
+ /**
+ * The function `_updateNegativeCount` updates a counter based on changes in frequency values.
+ * @param {number} freqCur - The current frequency value.
+ * @param {number} freqNew - The freqNew parameter represents the new frequency value.
+ */
+ protected _updateNegativeCount(freqCur: number, freqNew: number): void {
+ if (freqCur < 0 && freqNew >= 0) {
+ this._negativeCount--;
+ } else if (freqCur >= 0 && freqNew < 0) {
+ this._negativeCount++;
+ }
+ }
+
+ /**
+ * The `_update` function updates the values in a binary indexed freqMap starting from a given index and
+ * propagating the changes to its parent nodes.
+ * @param {number} index - The `index` parameter is a number that represents the index of the element in
+ * the data structure that needs to be updated.
+ * @param {number} delta - The `delta` parameter represents the change in value that needs to be
+ * applied to the elements in the data structure.
+ */
+ protected _update(index: number, delta: number): void {
+ index = index + 1;
+
+ while (index <= this.max) {
+ this._updateFrequency(index, delta);
+ index += index & -index;
+ }
+ }
+
+ /**
+ * The `_writeSingle` function updates the frequency at a specific index and triggers a callback if
+ * the frequency has changed.
+ * @param {number} index - The `index` parameter is a number that represents the index of the element
+ * being modified or accessed.
+ * @param {number} freq - The `freq` parameter represents the new frequency value that needs to be
+ * written to the specified index `index`.
+ */
+ protected _writeSingle(index: number, freq: number): void {
+ const freqCur = this._readSingle(index);
+
+ this._update(index, freq - freqCur);
+ this._updateNegativeCount(freqCur, freq);
+ }
+
+ /**
+ * The `_read` function calculates the sum of values in a binary freqMap up to a given count.
+ * @param {number} count - The `count` parameter is a number that represents the number of elements
+ * to read from the freqMap.
+ * @returns the sum of the values obtained from calling the `_getFrequency` method for each index in the
+ * range from `count` to 1.
+ */
+ protected _read(count: number): number {
+ let index = count;
+ let sum = 0;
+ while (index) {
+ sum += this._getFrequency(index);
+ index -= index & -index;
+ }
+
+ return sum;
+ }
+
+ /**
+ * The function `_binarySearch` performs a binary search to find the largest number that satisfies a given
+ * condition.
+ * @param {number} sum - The sum parameter is a number that represents the target sum value.
+ * @param before - The `before` parameter is a function that takes two numbers `x` and `y` as
+ * arguments and returns a boolean value. It is used to determine if `x` is less than or equal to
+ * `y`. The purpose of this function is to compare two numbers and determine their order.
+ * @returns the value of the variable "left".
+ */
+ protected _binarySearch(sum: number, before: (x: number, y: number) => boolean): number {
+ let left = 0;
+ let right = this.msb << 1;
+ let sumT = sum;
+
+ while (right > left + 1) {
+ const middle = (left + right) >> 1;
+ const sumM = this._getFrequency(middle);
+
+ if (middle <= this.max && before(sumM, sumT)) {
+ sumT -= sumM;
+ left = middle;
+ } else {
+ right = middle;
+ }
+ }
+ return left;
}
}
diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts
index 4f1e942..e1b2446 100644
--- a/src/data-structures/binary-tree/binary-tree.ts
+++ b/src/data-structures/binary-tree/binary-tree.ts
@@ -6,208 +6,176 @@
* @license MIT License
*/
-import type {
- BinaryTreeNodeKey,
- BinaryTreeNodeNested,
- BinaryTreeNodeProperties,
- BinaryTreeNodeProperty,
- BinaryTreeOptions
-} from '../../types';
+import type {BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey} from '../../types';
+import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
import {IBinaryTree} from '../../interfaces';
-import {
- BinaryTreeDeletedResult,
- BinaryTreeNodePropertyName,
- DFSOrderPattern,
- FamilyPosition,
- LoopType,
- NodeOrPropertyName
-} from '../../types';
import {trampoline} from '../../utils';
+import {Queue} from '../queue';
-export class BinaryTreeNode = BinaryTreeNodeNested> {
+/**
+ * Represents a node in a binary tree.
+ * @template V - The type of data stored in the node.
+ * @template N - The type of the family relationship in the binary tree.
+ */
+export class BinaryTreeNode = BinaryTreeNode>> {
/**
- * The constructor function initializes a BinaryTreeNode object with a key and an optional value.
- * @param {BinaryTreeNodeKey} key - The `key` parameter is of type `BinaryTreeNodeKey` and represents the unique identifier
- * of the binary tree node. It is used to distinguish one node from another in the binary tree.
- * @param {V} [val] - The "val" parameter is an optional parameter of type V. It represents the value that will be
- * stored in the binary tree node. If no value is provided, it will be set to undefined.
+ * The key associated with the node.
*/
- constructor(key: BinaryTreeNodeKey, val?: V) {
+ key: BTNKey;
+
+ /**
+ * The value stored in the node.
+ */
+ value: V | undefined;
+
+ /**
+ * The parent node of the current node.
+ */
+ parent: N | null | undefined;
+
+ /**
+ * Creates a new instance of BinaryTreeNode.
+ * @param {BTNKey} key - The key associated with the node.
+ * @param {V} value - The value stored in the node.
+ */
+ constructor(key: BTNKey, value?: V) {
this.key = key;
- this.val = val;
+ this.value = value;
}
- key: BinaryTreeNodeKey;
+ protected _left: N | null | undefined;
- val: V | undefined;
-
- private _left: FAMILY | null | undefined;
-
- get left(): FAMILY | null | undefined {
+ /**
+ * Get the left child node.
+ */
+ get left(): N | null | undefined {
return this._left;
}
- set left(v: FAMILY | null | undefined) {
+ /**
+ * Set the left child node.
+ * @param {N | null | undefined} v - The left child node.
+ */
+ set left(v: N | null | undefined) {
if (v) {
- v.parent = this as unknown as FAMILY;
+ v.parent = this as unknown as N;
}
this._left = v;
}
- private _right: FAMILY | null | undefined;
+ protected _right: N | null | undefined;
- get right(): FAMILY | null | undefined {
+ /**
+ * Get the right child node.
+ */
+ get right(): N | null | undefined {
return this._right;
}
- set right(v: FAMILY | null | undefined) {
+ /**
+ * Set the right child node.
+ * @param {N | null | undefined} v - The right child node.
+ */
+ set right(v: N | null | undefined) {
if (v) {
- v.parent = this as unknown as FAMILY;
+ v.parent = this as unknown as N;
}
this._right = v;
}
- parent: FAMILY | null | undefined;
-
/**
- * The function determines the position of a node in a family tree structure.
- * @returns a value of type `FamilyPosition`.
+ * Get the position of the node within its family.
+ * @returns {FamilyPosition} - The family position of the node.
*/
get familyPosition(): FamilyPosition {
- const that = this as unknown as FAMILY;
- if (that.parent) {
- if (that.parent.left === that) {
- if (that.left || that.right) {
- return FamilyPosition.ROOT_LEFT;
- } else {
- return FamilyPosition.LEFT;
- }
- } else if (that.parent.right === that) {
- if (that.left || that.right) {
- return FamilyPosition.ROOT_RIGHT;
- } else {
- return FamilyPosition.RIGHT;
- }
- } else {
- return FamilyPosition.MAL_NODE;
- }
- } else {
- if (that.left || that.right) {
- return FamilyPosition.ROOT;
- } else {
- return FamilyPosition.ISOLATED;
- }
+ const that = this as unknown as N;
+ if (!this.parent) {
+ return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED;
}
+
+ if (this.parent.left === that) {
+ return this.left || this.right ? FamilyPosition.ROOT_LEFT : FamilyPosition.LEFT;
+ } else if (this.parent.right === that) {
+ return this.left || this.right ? FamilyPosition.ROOT_RIGHT : FamilyPosition.RIGHT;
+ }
+
+ return FamilyPosition.MAL_NODE;
}
}
-export class BinaryTree = BinaryTreeNode> implements IBinaryTree {
+/**
+ * Represents a binary tree data structure.
+ * @template N - The type of the binary tree's nodes.
+ */
+export class BinaryTree = BinaryTreeNode>>
+ implements IBinaryTree {
+ iterationType: IterationType = IterationType.ITERATIVE;
+
/**
- * This is a constructor function for a binary tree class that takes an optional options parameter.
- * @param {BinaryTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
- * constructor of the `BinaryTree` class. It allows you to customize the behavior of the binary tree by providing
- * different configuration options.
+ * Creates a new instance of BinaryTree.
+ * @param {BinaryTreeOptions} [options] - The options for the binary tree.
*/
constructor(options?: BinaryTreeOptions) {
if (options !== undefined) {
- const {loopType = LoopType.ITERATIVE} = options;
- this._loopType = loopType;
+ const {iterationType = IterationType.ITERATIVE} = options;
+ this.iterationType = iterationType;
}
}
- /**
- * The function creates a new binary tree node with an optional value.
- * @param {BinaryTreeNodeKey} key - The `key` parameter is the identifier for the binary tree node. It is of type
- * `BinaryTreeNodeKey`, which represents the unique identifier for each node in the binary tree.
- * @param [val] - The `val` parameter is an optional value that can be assigned to the node. It represents the value
- * stored in the node.
- * @returns a new instance of a BinaryTreeNode with the specified key and value.
- */
- createNode(key: BinaryTreeNodeKey, val?: N['val']): N {
- return new BinaryTreeNode(key, val) as N;
- }
- // TODO placeholder node may need redesigned
- private _root: N | null = null;
+ protected _root: N | null = null;
+ /**
+ * Get the root node of the binary tree.
+ */
get root(): N | null {
return this._root;
}
- private _size = 0;
+ protected _size = 0;
+ /**
+ * Get the number of nodes in the binary tree.
+ */
get size(): number {
return this._size;
}
- private _loopType: LoopType = LoopType.ITERATIVE;
-
- get loopType(): LoopType {
- return this._loopType;
- }
-
- visitedKey: BinaryTreeNodeKey[] = [];
-
- visitedVal: N['val'][] = [];
-
- visitedNode: N[] = [];
-
/**
- * The `swapLocation` function swaps the location of two nodes in a binary tree.
- * @param {N} srcNode - The source node that you want to swap with the destination node.
- * @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
- * be swapped to.
- * @returns The `destNode` is being returned.
+ * Creates a new instance of BinaryTreeNode with the given key and value.
+ * @param {BTNKey} key - The key for the new node.
+ * @param {V} value - The value for the new node.
+ * @returns {N} - The newly created BinaryTreeNode.
*/
- swapLocation(srcNode: N, destNode: N): N {
- const {key, val} = destNode;
- const tempNode = this.createNode(key, val);
-
- if (tempNode) {
- destNode.key = srcNode.key;
- destNode.val = srcNode.val;
-
- srcNode.key = tempNode.key;
- srcNode.val = tempNode.val;
- }
-
- return destNode;
+ createNode(key: BTNKey, value?: V): N {
+ return new BinaryTreeNode(key, value) as N;
}
/**
- * The clear() function resets the root, size, and maxKey properties to their initial values.
+ * Clear the binary tree, removing all nodes.
*/
clear() {
- this._root = null;
+ this._setRoot(null);
this._size = 0;
- this._clearResults();
}
/**
- * The function checks if the size of an object is equal to zero and returns a boolean value.
- * @returns A boolean value indicating whether the size of the object is 0 or not.
+ * Check if the binary tree is empty.
+ * @returns {boolean} - True if the binary tree is empty, false otherwise.
*/
isEmpty(): boolean {
return this.size === 0;
}
/**
- * When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
- * In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
+ * Add a node with the given key and value to the binary tree.
+ * @param {BTNKey | N | null} keyOrNode - The key or node to add to the binary tree.
+ * @param {V} value - The value for the new node (optional).
+ * @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
*/
-
- /**
- * The `add` function adds a new node to a binary tree, either by ID or by creating a new node with a given value.
- * @param {BinaryTreeNodeKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a `BinaryTreeNodeKey`, which
- * is a number representing the ID of a binary tree node, or it can be a `N` object, which represents a binary tree
- * node itself. It can also be `null` if no node is specified.
- * @param [val] - The `val` parameter is an optional value that can be assigned to the `val` property of the new node
- * being added to the binary tree.
- * @returns The function `add` returns either the inserted node (`N`), `null`, or `undefined`.
- */
- add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined {
+ add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
- const queue: Array = [root];
- while (queue.length > 0) {
+ const queue = new Queue([root]);
+ while (queue.size > 0) {
const cur = queue.shift();
if (cur) {
if (newNode && cur.key === newNode.key) return;
@@ -225,18 +193,19 @@ export class BinaryTree = BinaryTreeNode>
if (keyOrNode === null) {
needInsert = null;
} else if (typeof keyOrNode === 'number') {
- needInsert = this.createNode(keyOrNode, val);
+ needInsert = this.createNode(keyOrNode, value);
} else if (keyOrNode instanceof BinaryTreeNode) {
needInsert = keyOrNode;
} else {
return;
}
- const existNode = keyOrNode ? this.get(keyOrNode, 'key') : undefined;
+ const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
+ const existNode = key !== undefined ? this.get(key, (node: N) => node.key) : undefined;
if (this.root) {
if (existNode) {
- existNode.val = val;
+ existNode.value = value;
inserted = existNode;
} else {
inserted = _bfs(this.root, needInsert);
@@ -244,9 +213,9 @@ export class BinaryTree = BinaryTreeNode>
} else {
this._setRoot(needInsert);
if (needInsert !== null) {
- this._setSize(1);
+ this._size = 1;
} else {
- this._setSize(0);
+ this._size = 0;
}
inserted = this.root;
}
@@ -256,61 +225,72 @@ export class BinaryTree = BinaryTreeNode>
/**
* The `addMany` function takes an array of binary tree node IDs or nodes, and optionally an array of corresponding data
* values, and adds them to the binary tree.
- * @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of BinaryTreeNodeKey or BinaryTreeNode
+ * @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of BTNKey or BinaryTreeNode
* objects, or null values.
- * @param {N['val'][]} [data] - The `data` parameter is an optional array of values (`N['val'][]`) that corresponds to
- * the nodes or node IDs being added. It is used to set the value of each node being added. If `data` is not provided,
+ * @param {V[]} [values] - The `values` parameter is an optional array of values (`V[]`) that corresponds to
+ * the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided,
* the value of the nodes will be `undefined`.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
- addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: N['val'][]): (N | null | undefined)[] {
+ addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], values?: V[]): (N | null | undefined)[] {
// TODO not sure addMany not be run multi times
- const inserted: (N | null | undefined)[] = [];
-
- for (let i = 0; i < keysOrNodes.length; i++) {
- const keyOrNode = keysOrNodes[i];
+ return keysOrNodes.map((keyOrNode, i) => {
if (keyOrNode instanceof BinaryTreeNode) {
- inserted.push(this.add(keyOrNode.key, keyOrNode.val));
- continue;
+ return this.add(keyOrNode.key, keyOrNode.value);
}
if (keyOrNode === null) {
- inserted.push(this.add(null));
- continue;
+ return this.add(null);
}
- const val = data?.[i];
- inserted.push(this.add(keyOrNode, val));
- }
- return inserted;
+ const value = values?.[i];
+ return this.add(keyOrNode, value);
+ });
}
/**
* The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
- * @param {(BinaryTreeNodeKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
- * `BinaryTreeNodeKey` or `N` values.
- * @param {N[] | Array} [data] - The `data` parameter is an optional array of values that will be assigned to
+ * @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
+ * `BTNKey` or `N` values.
+ * @param {N[] | Array} [data] - The `data` parameter is an optional array of values that will be assigned to
* the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
* array. Each value in the `data` array will be assigned to the
* @returns The method is returning a boolean value.
*/
- refill(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: N[] | Array): boolean {
+ refill(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: Array): boolean {
this.clear();
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
}
+ delete>(identifier: BTNKey, callback?: C): BinaryTreeDeletedResult[];
+
+ delete>(identifier: N | null, callback?: C): BinaryTreeDeletedResult[];
+
+ delete>(identifier: ReturnType, callback: C): BinaryTreeDeletedResult[];
+
/**
- * The `remove` function in TypeScript is used to delete a node from a binary search tree and returns an array of objects
- * containing the deleted node and the node that needs to be balanced.
- * @param {N | BinaryTreeNodeKey} nodeOrKey - The `nodeOrKey` parameter can be either a node object (`N`) or a binary tree
- * node ID (`BinaryTreeNodeKey`).
- * @returns The function `remove` returns an array of `BinaryTreeDeletedResult` objects.
+ * The `delete` function removes a node from a binary search tree and returns the deleted node along
+ * with the parent node that needs to be balanced.
+ * a key (`BTNKey`). If it is a key, the function will find the corresponding node in the
+ * binary tree.
+ * @returns an array of `BinaryTreeDeletedResult` objects.
+ * @param {ReturnType} identifier - The `identifier` parameter is either a
+ * `BTNKey` or a generic type `N`. It represents the property of the node that we are
+ * searching for. It can be a specific key value or any other property of the node.
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
+ * included in the result. The `callback` parameter has a default value of
+ * `((node: N) => node.key)`, which
*/
- remove(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult[] {
+ delete>(
+ identifier: ReturnType | null,
+ callback: C = ((node: N) => node.key) as C
+ ): BinaryTreeDeletedResult[] {
const bstDeletedResult: BinaryTreeDeletedResult[] = [];
if (!this.root) return bstDeletedResult;
+ if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
- const curr: N | null = typeof nodeOrKey === 'number' ? this.get(nodeOrKey) : nodeOrKey;
+ const curr = this.get(identifier, callback);
if (!curr) return bstDeletedResult;
const parent: N | null = curr?.parent ? curr.parent : null;
@@ -319,7 +299,8 @@ export class BinaryTree = BinaryTreeNode>
if (!curr.left) {
if (!parent) {
- if (curr.right !== undefined) this._setRoot(curr.right);
+ // Handle the case when there's only one root node
+ this._setRoot(null);
} else {
const {familyPosition: fp} = curr;
if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
@@ -333,7 +314,7 @@ export class BinaryTree = BinaryTreeNode>
const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
if (leftSubTreeRightMost) {
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
- orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
+ orgCurrent = this._swap(curr, leftSubTreeRightMost);
if (parentOfLeftSubTreeMax) {
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
@@ -342,21 +323,27 @@ export class BinaryTree = BinaryTreeNode>
}
}
}
- this._setSize(this.size - 1);
+ this._size = this.size - 1;
bstDeletedResult.push({deleted: orgCurrent, needBalanced});
return bstDeletedResult;
}
/**
- * The function calculates the depth of a node in a binary tree.
- * @param {N | BinaryTreeNodeKey | null} distNode - The `distNode` parameter can be any node of the tree
- * @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter can be the predecessor node of distNode
- * @returns the depth of the given node or binary tree.
+ * The function `getDepth` calculates the depth of a given node in a binary tree relative to a
+ * specified root node.
+ * @param {BTNKey | N | null} distNode - The `distNode` parameter represents the node
+ * whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
+ * of the node (`BTNKey`), or `null`.
+ * @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter represents the
+ * starting node from which we want to calculate the depth. It can be either a node object or the key
+ * of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
+ * node of the binary tree.
+ * @returns the depth of the `distNode` relative to the `beginRoot`.
*/
- getDepth(distNode: N | BinaryTreeNodeKey | null, beginRoot: N | BinaryTreeNodeKey | null = this.root): number {
- if (typeof distNode === 'number') distNode = this.get(distNode, 'key');
- if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot, 'key');
+ getDepth(distNode: BTNKey | N | null, beginRoot: BTNKey | N | null = this.root): number {
+ if (typeof distNode === 'number') distNode = this.get(distNode);
+ if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
let depth = 0;
while (distNode?.parent) {
if (distNode === beginRoot) {
@@ -369,17 +356,22 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The `getHeight` function calculates the maximum height of a binary tree, either recursively or iteratively.
- * @param {N | BinaryTreeNodeKey | null} [beginRoot] - The `beginRoot` parameter is optional and can be of type `N` (a
- * generic type representing a node in a binary tree), `BinaryTreeNodeKey` (a type representing the ID of a binary tree
- * node), or `null`.
+ * The `getHeight` function calculates the maximum height of a binary tree using either recursive or
+ * iterative approach.
+ * @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter represents the
+ * starting node from which the height of the binary tree is calculated. It can be either a node
+ * object (`N`), a key value of a node in the tree (`BTNKey`), or `null` if no starting
+ * node is specified. If `
+ * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
+ * height of the binary tree using a recursive approach or an iterative approach. It can have two
+ * possible values:
* @returns the height of the binary tree.
*/
- getHeight(beginRoot: N | BinaryTreeNodeKey | null = this.root): number {
- if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot, 'key');
+ getHeight(beginRoot: BTNKey | N | null = this.root, iterationType = this.iterationType): number {
+ if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
if (!beginRoot) return -1;
- if (this._loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _getMaxHeight = (cur: N | null | undefined): number => {
if (!cur) return -1;
const leftHeight = _getMaxHeight(cur.left);
@@ -393,7 +385,7 @@ export class BinaryTree = BinaryTreeNode>
return -1;
}
- const stack: {node: N; depth: number}[] = [{node: beginRoot, depth: 0}];
+ const stack: { node: N; depth: number }[] = [{node: beginRoot, depth: 0}];
let maxHeight = 0;
while (stack.length > 0) {
@@ -415,17 +407,19 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The `getMinHeight` function calculates the minimum height of a binary tree using either a recursive or iterative
- * approach.
- * @param {N | null} [beginRoot] - The `beginRoot` parameter is an optional parameter of type `N` or `null`. It
- * represents the starting node from which to calculate the minimum height of a binary tree. If no value is provided
- * for `beginRoot`, the `this.root` property is used as the default value.
- * @returns The function `getMinHeight` returns the minimum height of the binary tree.
+ * The `getMinHeight` function calculates the minimum height of a binary tree using either a
+ * recursive or iterative approach.
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which we want to
+ * calculate the minimum height of the tree. It is optional and defaults to the root of the tree if
+ * not provided.
+ * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
+ * to calculate the minimum height of a binary tree. It can have two possible values:
+ * @returns The function `getMinHeight` returns the minimum height of a binary tree.
*/
- getMinHeight(beginRoot: N | null = this.root): number {
+ getMinHeight(beginRoot: N | null = this.root, iterationType = this.iterationType): number {
if (!beginRoot) return -1;
- if (this._loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _getMinHeight = (cur: N | null | undefined): number => {
if (!cur) return 0;
if (!cur.left && !cur.right) return 0;
@@ -465,154 +459,238 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the height of the
- * tree.
- * @param {N | null} [beginRoot] - The parameter `beginRoot` is of type `N` or `null`. It represents the root node of a
- * tree or null if the tree is empty.
+ * The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
+ * height of the tree.
+ * @param {N | null} beginRoot - The parameter `beginRoot` is of type `N | null`, which means it can
+ * either be of type `N` (representing a node in a tree) or `null` (representing an empty tree).
* @returns The method is returning a boolean value.
*/
isPerfectlyBalanced(beginRoot: N | null = this.root): boolean {
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
}
+ getNodes>(
+ identifier: BTNKey,
+ callback?: C,
+ onlyOne?: boolean,
+ beginRoot?: N | null,
+ iterationType?: IterationType
+ ): N[];
+
+ getNodes>(
+ identifier: N | null,
+ callback?: C,
+ onlyOne?: boolean,
+ beginRoot?: N | null,
+ iterationType?: IterationType
+ ): N[];
+
+ getNodes>(
+ identifier: ReturnType,
+ callback: C,
+ onlyOne?: boolean,
+ beginRoot?: N | null,
+ iterationType?: IterationType
+ ): N[];
+
/**
- * The function `getNodes` returns an array of nodes that match a given property name and value in a binary tree.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or a
- * generic type `N`. It represents the property of the binary tree node that you want to search for.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name to use when searching for nodes. If not provided, it defaults to 'key'.
- * @param {boolean} [onlyOne] - The `onlyOne` parameter is an optional boolean parameter that determines whether to
- * return only one node that matches the given `nodeProperty` or `propertyName`. If `onlyOne` is set to `true`, the
- * function will stop traversing the tree and return the first matching node. If `only
- * @returns an array of nodes (type N).
+ * The function `getNodes` returns an array of nodes that match a given node property, using either
+ * recursive or iterative traversal.
+ * @param {ReturnType} identifier - The `identifier` parameter is either a
+ * `BTNKey` or a generic type `N`. It represents the property of the node that we are
+ * searching for. It can be a specific key value or any other property of the node.
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
+ * included in the result. The `callback` parameter has a default value of
+ * `((node: N) => node.key)`, which
+ * @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
+ * first node that matches the identifier. If set to true, the function will return an array with
+ * only one element (or an empty array if no matching node is found). If set to false (default), the
+ * function will continue searching for all
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which the
+ * traversal of the binary tree will begin. It is optional and defaults to the root of the binary
+ * tree.
+ * @param iterationType - The `iterationType` parameter determines the type of iteration used to
+ * traverse the binary tree. It can have two possible values:
+ * @returns The function `getNodes` returns an array of nodes (`N[]`).
*/
- getNodes(
- nodeProperty: BinaryTreeNodeKey | N,
- propertyName: BinaryTreeNodePropertyName = 'key',
- onlyOne = false
+ getNodes>(
+ identifier: ReturnType | null,
+ callback: C = ((node: N) => node.key) as C,
+ onlyOne = false,
+ beginRoot: N | null = this.root,
+ iterationType = this.iterationType
): N[] {
- if (!this.root) return [];
+ if (!beginRoot) return [];
+ if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
+ const ans: N[] = [];
- const result: N[] = [];
-
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return;
+ if (callback(cur) === identifier) {
+ ans.push(cur);
+ if (onlyOne) return;
+ }
if (!cur.left && !cur.right) return;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
};
- _traverse(this.root);
+ _traverse(beginRoot);
} else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
+ const queue = new Queue([beginRoot]);
+ while (queue.size > 0) {
const cur = queue.shift();
if (cur) {
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return result;
+ if (callback(cur) === identifier) {
+ ans.push(cur);
+ if (onlyOne) return ans;
+ }
cur.left && queue.push(cur.left);
cur.right && queue.push(cur.right);
}
}
}
- return result;
+ return ans;
}
+ has>(
+ identifier: BTNKey,
+ callback?: C,
+ beginRoot?: N,
+ iterationType?: IterationType
+ ): boolean;
+
+ has>(
+ identifier: N | null,
+ callback?: C,
+ beginRoot?: N,
+ iterationType?: IterationType
+ ): boolean;
+
+ has>(
+ identifier: ReturnType | null,
+ callback: C,
+ beginRoot?: N,
+ iterationType?: IterationType
+ ): boolean;
+
/**
- * The function checks if a binary tree node has a specific property.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or `N`.
- * It represents the property of the binary tree node that you want to check.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the name of the property to be checked in the nodes. If not provided, it defaults to 'key'.
+ * The function checks if a binary tree has a node with a given property or key.
+ * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
+ * the node that you want to find in the binary tree. It can be either a `BTNKey` or a
+ * generic type `N`.
+ * @param callback - The `callback` parameter is a function that is used to determine whether a node
+ * matches the desired criteria. It takes a node as input and returns a boolean value indicating
+ * whether the node matches the criteria or not. The default callback function
+ * `((node: N) => node.key)` is used if no callback function is
+ * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
+ * the node from which the search should begin. By default, it is set to `this.root`, which means the
+ * search will start from the root node of the binary tree. However, you can provide a different node
+ * as
+ * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
+ * performed when searching for nodes in the binary tree. It can have one of the following values:
* @returns a boolean value.
*/
- has(nodeProperty: BinaryTreeNodeKey | N, propertyName: BinaryTreeNodePropertyName = 'key'): boolean {
+ has>(
+ identifier: ReturnType | null,
+ callback: C = ((node: N) => node.key) as C,
+ beginRoot = this.root,
+ iterationType = this.iterationType
+ ): boolean {
+ if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
// TODO may support finding node by value equal
- return this.getNodes(nodeProperty, propertyName).length > 0;
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
+ }
+
+ get>(
+ identifier: BTNKey,
+ callback?: C,
+ beginRoot?: N,
+ iterationType?: IterationType
+ ): N | null;
+
+ get>(
+ identifier: N | null,
+ callback?: C,
+ beginRoot?: N,
+ iterationType?: IterationType
+ ): N | null;
+
+ get>(
+ identifier: ReturnType,
+ callback: C,
+ beginRoot?: N,
+ iterationType?: IterationType
+ ): N | null;
+
+ /**
+ * The function `get` returns the first node in a binary tree that matches the given property or key.
+ * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
+ * the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
+ * type.
+ * @param callback - The `callback` parameter is a function that is used to determine whether a node
+ * matches the desired criteria. It takes a node as input and returns a boolean value indicating
+ * whether the node matches the criteria or not. The default callback function
+ * (`((node: N) => node.key)`) is used if no callback function is
+ * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
+ * the root node from which the search should begin.
+ * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
+ * performed when searching for a node in the binary tree. It can have one of the following values:
+ * @returns either the found node (of type N) or null if no node is found.
+ */
+ get>(
+ identifier: ReturnType | null,
+ callback: C = ((node: N) => node.key) as C,
+ beginRoot = this.root,
+ iterationType = this.iterationType
+ ): N | null {
+ if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
+ // TODO may support finding node by value equal
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
}
/**
- * The function returns the first node that matches the given property name and value, or null if no matching node is
- * found.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or `N`.
- * It represents the property of the binary tree node that you want to search for.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name to be used for searching the binary tree nodes. If this parameter is not provided, the
- * default value is set to `'key'`.
- * @returns either the value of the specified property of the node, or the node itself if no property name is provided.
- * If no matching node is found, it returns null.
+ * The function `getPathToRoot` returns an array of nodes starting from a given node and traversing
+ * up to the root node, with the option to reverse the order of the nodes.
+ * @param {N} beginRoot - The `beginRoot` parameter represents the starting node from which you want
+ * to find the path to the root node.
+ * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
+ * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
+ * reversed before returning it. If `isReverse` is set to `false` or not provided, the path will
+ * @returns The function `getPathToRoot` returns an array of type `N[]`.
*/
- get(nodeProperty: BinaryTreeNodeKey | N, propertyName: BinaryTreeNodePropertyName = 'key'): N | null {
- // TODO may support finding node by value equal
- return this.getNodes(nodeProperty, propertyName, true)[0] ?? null;
- }
-
- /**
- * The function `getPathToRoot` returns an array of nodes representing the path from a given node to the root node, with
- * an option to reverse the order of the nodes.
- * @param {N} node - The `node` parameter represents a node in a tree structure. It is of type `N`, which could be any
- * type that represents a node in your specific implementation.
- * @param {boolean} [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the resulting
- * path should be reversed or not. If `isReverse` is set to `true`, the path will be reversed before returning it. If
- * `isReverse` is set to `false` or not provided, the path will
- * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
- */
- getPathToRoot(node: N, isReverse = true): N[] {
+ getPathToRoot(beginRoot: N, isReverse = true): N[] {
// TODO to support get path through passing key
const result: N[] = [];
- while (node.parent) {
+ while (beginRoot.parent) {
// Array.push + Array.reverse is more efficient than Array.unshift
// TODO may consider using Deque, so far this is not the performance bottleneck
- result.push(node);
- node = node.parent;
+ result.push(beginRoot);
+ beginRoot = beginRoot.parent;
}
- result.push(node);
+ result.push(beginRoot);
return isReverse ? result.reverse() : result;
}
/**
- * The function `getLeftMost` returns the leftmost node in a binary tree, starting from a specified node or the root if
- * no node is specified.
- * generic type representing a node in a binary tree), `BinaryTreeNodeKey` (a type representing the ID of a binary tree
- * node), or `null`.
- * @returns The function `getLeftMost` returns the leftmost node in a binary tree. If the `beginRoot` parameter is
- * provided, it starts the traversal from that node. If `beginRoot` is not provided or is `null`, it starts the traversal
- * from the root of the binary tree. The function returns the leftmost node found during the traversal. If no leftmost
- * node is found (
+ * The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
+ * iterative traversal.
+ * @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
+ * for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
+ * of a node (`BTNKey`), or `null` if the tree is empty.
+ * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
+ * be performed when finding the leftmost node in a binary tree. It can have two possible values:
+ * @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
+ * no leftmost node, it returns `null`.
*/
- getLeftMost(): N | null;
-
- /**
- * The function `getLeftMost` returns the leftmost node in a binary tree, starting from a specified node or the root if
- * no node is specified.
- * @param {N | BinaryTreeNodeKey | null} [node] - The `beginRoot` parameter is optional and can be of type `N` (a
- * generic type representing a node in a binary tree), `BinaryTreeNodeKey` (a type representing the ID of a binary tree
- * node).
- * @returns The function `getLeftMost` returns the leftmost node in a binary tree. If the `beginRoot` parameter is
- * provided, it starts the traversal from that node. If `beginRoot` is not provided or is `null`, it starts the traversal
- * from the root of the binary tree. The function returns the leftmost node found during the traversal. If no leftmost
- * node is found (
- */
- getLeftMost(node: N): N;
-
- /**
- * The function `getLeftMost` returns the leftmost node in a binary tree, starting from a specified node or the root if
- * no node is specified.
- * @param {N | BinaryTreeNodeKey | null} [beginRoot] - The `beginRoot` parameter is optional and can be of type `N` (a
- * generic type representing a node in a binary tree), `BinaryTreeNodeKey` (a type representing the ID of a binary tree
- * node), or `null`.
- * @returns The function `getLeftMost` returns the leftmost node in a binary tree. If the `beginRoot` parameter is
- * provided, it starts the traversal from that node. If `beginRoot` is not provided or is `null`, it starts the traversal
- * from the root of the binary tree. The function returns the leftmost node found during the traversal. If no leftmost
- * node is found (
- */
- getLeftMost(beginRoot: N | BinaryTreeNodeKey | null = this.root): N | null {
- if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot, 'key');
+ getLeftMost(beginRoot: BTNKey | N | null = this.root, iterationType = this.iterationType): N | null {
+ if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
if (!beginRoot) return beginRoot;
- if (this._loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.left) return cur;
return _traverse(cur.left);
@@ -631,39 +709,21 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The `getRightMost` function returns the rightmost node in a binary tree, either recursively or iteratively using tail
- * recursion optimization.
- * @returns The `getRightMost` function returns the rightmost node in a binary tree. It returns the
- * rightmost node starting from the root of the binary tree.
+ * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
+ * iteratively.
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node from which we want to
+ * find the rightmost node. It is of type `N | null`, which means it can either be a node of type `N`
+ * or `null`. If it is `null`, it means there is no starting node
+ * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
+ * be performed when finding the rightmost node in a binary tree. It can have two possible values:
+ * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If the
+ * `beginRoot` parameter is `null`, it returns `null`.
*/
- getRightMost(): N | null;
-
- /**
- * The `getRightMost` function returns the rightmost node in a binary tree, either recursively or iteratively using tail
- * recursion optimization.
- * @param {N | null} [beginRoot] - The `node` parameter is an optional parameter of type `N` or `null`. It represents the
- * starting node from which we want to find the rightmost node. If no node is provided, the function will default to
- * using the root node of the data structure.
- * @returns The `getRightMost` function returns the rightmost node in a binary tree. It returns the rightmost node
- * starting from that node.
- */
- getRightMost(beginRoot: N): N;
-
- /**
- * The `getRightMost` function returns the rightmost node in a binary tree, either recursively or iteratively using tail
- * recursion optimization.
- * @param {N | null} [beginRoot] - The `node` parameter is an optional parameter of type `N` or `null`. It represents the
- * starting node from which we want to find the rightmost node. If no node is provided, the function will default to
- * using the root node of the data structure.
- * @returns The `getRightMost` function returns the rightmost node in a binary tree. If the `node` parameter is provided,
- * it returns the rightmost node starting from that node. If the `node` parameter is not provided, it returns the
- * rightmost node starting from the root of the binary tree.
- */
- getRightMost(beginRoot: N | null = this.root): N | null {
+ getRightMost(beginRoot: N | null = this.root, iterationType = this.iterationType): N | null {
// TODO support get right most by passing key in
if (!beginRoot) return beginRoot;
- if (this._loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.right) return cur;
return _traverse(cur.right);
@@ -682,26 +742,30 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The function checks if a binary search tree is valid by traversing it either recursively or iteratively.
- * @param {N | null} node - The `node` parameter represents the root node of a binary search tree (BST).
- * @returns a boolean value.
+ * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
+ * @param {N} beginRoot - The `beginRoot` parameter is the root node of the binary tree that you want
+ * to check if it is a binary search tree (BST) subtree.
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
+ * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
+ * possible values:
+ * @returns The function `isSubtreeBST` returns a boolean value.
*/
- isSubtreeBST(node: N | null): boolean {
+ isSubtreeBST(beginRoot: N | null, iterationType = this.iterationType): boolean {
// TODO there is a bug
- if (!node) return true;
+ if (!beginRoot) return true;
- if (this._loopType === LoopType.RECURSIVE) {
- const dfs = (cur: N | null | undefined, min: BinaryTreeNodeKey, max: BinaryTreeNodeKey): boolean => {
+ if (iterationType === IterationType.RECURSIVE) {
+ const dfs = (cur: N | null | undefined, min: BTNKey, max: BTNKey): boolean => {
if (!cur) return true;
if (cur.key <= min || cur.key >= max) return false;
return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
};
- return dfs(node, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
+ return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
} else {
const stack = [];
let prev = Number.MIN_SAFE_INTEGER,
- curr: N | null | undefined = node;
+ curr: N | null | undefined = beginRoot;
while (curr || stack.length > 0) {
while (curr) {
stack.push(curr);
@@ -717,522 +781,246 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The function isBST checks if the binary tree is valid binary search tree.
- * @returns The `isBST()` function is returning a boolean value.
- */
- isBST(): boolean {
- return this.isSubtreeBST(this.root);
- }
-
- /**
- * The function calculates the size of a subtree by traversing it either recursively or iteratively.
- * @param {N | null | undefined} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree in a
- * binary tree.
- * @returns the size of the subtree rooted at `subTreeRoot`.
- */
- getSubTreeSize(subTreeRoot: N | null | undefined) {
- // TODO support key passed in
- let size = 0;
- if (!subTreeRoot) return size;
-
- if (this._loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N) => {
- size++;
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
- };
-
- _traverse(subTreeRoot);
- return size;
- } else {
- const stack: N[] = [subTreeRoot];
-
- while (stack.length > 0) {
- const cur = stack.pop()!;
- size++;
- cur.right && stack.push(cur.right);
- cur.left && stack.push(cur.left);
- }
-
- return size;
- }
- }
-
- /**
- * The function `subTreeSum` calculates the sum of a specified property in a binary tree or subtree.
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
- * tree or the ID of a binary tree node. It can also be `null` if there is no subtree.
- * @param {BinaryTreeNodePropertyName} [propertyName] - propertyName is an optional parameter that specifies the
- * property of the binary tree node to use for calculating the sum. It can be either 'key' or 'val'. If propertyName is
- * not provided, it defaults to 'key'.
- * @returns a number, which is the sum of the values of the specified property in the subtree rooted at `subTreeRoot`.
- */
- subTreeSum(subTreeRoot: N | BinaryTreeNodeKey | null, propertyName: BinaryTreeNodePropertyName = 'key'): number {
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
-
- if (!subTreeRoot) return 0;
-
- let sum = 0;
-
- const _sumByProperty = (cur: N) => {
- let needSum: number;
- switch (propertyName) {
- case 'key':
- needSum = cur.key;
- break;
- case 'val':
- needSum = typeof cur.val === 'number' ? cur.val : 0;
- break;
- default:
- needSum = cur.key;
- break;
- }
- return needSum;
- };
-
- if (this._loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N): void => {
- sum += _sumByProperty(cur);
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
- };
-
- _traverse(subTreeRoot);
- } else {
- const stack: N[] = [subTreeRoot];
-
- while (stack.length > 0) {
- const cur = stack.pop()!;
- sum += _sumByProperty(cur);
- cur.right && stack.push(cur.right);
- cur.left && stack.push(cur.left);
- }
- }
-
- return sum;
- }
-
- /**
- * The function `subTreeAdd` adds a delta value to a specified property of each node in a subtree.
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
- * tree or the ID of a node in the binary tree. It can also be `null` if there is no subtree to add to.
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the property value of
- * each node in the subtree should be incremented.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'key'.
+ * The function checks if a binary tree is a binary search tree.
+ * @param iterationType - The parameter "iterationType" is used to specify the type of iteration to
+ * be used when checking if the binary tree is a binary search tree (BST). It is an optional
+ * parameter with a default value of "this.iterationType". The value of "this.iterationType" is not
+ * provided in
* @returns a boolean value.
*/
- subTreeAdd(
- subTreeRoot: N | BinaryTreeNodeKey | null,
- delta: number,
- propertyName: BinaryTreeNodePropertyName = 'key'
- ): boolean {
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
+ isBST(iterationType = this.iterationType): boolean {
+ if (this.root === null) return true;
+ return this.isSubtreeBST(this.root, iterationType);
+ }
- if (!subTreeRoot) return false;
+ /**
+ * The function `subTreeTraverse` traverses a binary tree and applies a callback function to each
+ * node, either recursively or iteratively.
+ * @param callback - The `callback` parameter is a function that will be called on each node in the
+ * subtree traversal. It takes a single argument, which is the current node being traversed, and
+ * returns a value. The return values from each callback invocation will be collected and returned as
+ * an array.
+ * @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
+ * for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
+ * start from the root of the tree.
+ * @param iterationType - The `iterationType` parameter determines the type of traversal to be
+ * performed on the binary tree. It can have two possible values:
+ * @returns The function `subTreeTraverse` returns an array of `ReturnType>`.
+ */
+ subTreeTraverse>(
+ callback: C = ((node: N) => node.key) as C,
+ beginRoot: BTNKey | N | null = this.root,
+ iterationType = this.iterationType
+ ): ReturnType[] {
+ if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
- const _addByProperty = (cur: N) => {
- switch (propertyName) {
- case 'key':
- cur.key += delta;
- break;
- default:
- cur.key += delta;
- break;
- }
- };
+ const ans: ReturnType>[] = [];
+ if (!beginRoot) return ans;
- if (this._loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
- _addByProperty(cur);
+ ans.push(callback(cur));
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
};
- _traverse(subTreeRoot);
+ _traverse(beginRoot);
} else {
- const stack: N[] = [subTreeRoot];
+ const stack: N[] = [beginRoot];
while (stack.length > 0) {
const cur = stack.pop()!;
- _addByProperty(cur);
+ ans.push(callback(cur));
cur.right && stack.push(cur.right);
cur.left && stack.push(cur.left);
}
}
- return true;
+ return ans;
}
/**
- * Performs a breadth-first search (bfs) on a binary tree, accumulating properties of each node based on their 'key' property.
- * @returns An array of binary tree node IDs.
+ * The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback
+ * function on each node according to a specified order pattern.
+ * @param callback - The `callback` parameter is a function that will be called on each node during
+ * the depth-first search traversal. It takes a node as input and returns a value. The default value
+ * is `((node: N) => node.key)`, which is a callback function defined elsewhere in the code.
+ * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
+ * nodes are visited during the depth-first search. There are three possible values for `pattern`:
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
+ * search. It determines where the search will begin in the tree or graph structure. If `beginRoot`
+ * is `null`, an empty array will be returned.
+ * @param {IterationType} iterationType - The `iterationType` parameter determines the type of
+ * iteration used in the depth-first search algorithm. It can have two possible values:
+ * @returns The function `dfs` returns an array of `ReturnType>` values.
*/
- bfs(): BinaryTreeNodeKey[];
-
- /**
- * Performs a breadth-first search (bfs) on a binary tree, accumulating properties of each node based on the specified property name.
- * @param {'key'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of values corresponding to the specified property.
- */
- bfs(nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
-
- /**
- * Performs a breadth-first search (bfs) on a binary tree, accumulating the 'val' property of each node.
- * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of 'val' properties from each node.
- */
- bfs(nodeOrPropertyName: 'val'): N['val'][];
-
- /**
- * Performs a breadth-first search (bfs) on a binary tree, accumulating nodes themselves.
- * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of binary tree nodes.
- */
- bfs(nodeOrPropertyName: 'node'): N[];
-
- /**
- * The bfs function performs a breadth-first search on a binary tree, accumulating properties of each node based on a specified property name.
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - An optional parameter that represents either a node or a property name.
- * If a node is provided, the bfs algorithm will be performed starting from that node.
- * If a property name is provided, the bfs algorithm will be performed starting from the root node, accumulating the specified property.
- * @returns An instance of the `BinaryTreeNodeProperties` class with generic type `N`.
- */
- bfs(nodeOrPropertyName: NodeOrPropertyName = 'key'): BinaryTreeNodeProperties {
- this._clearResults();
- const queue: Array = [this.root];
-
- while (queue.length !== 0) {
- const cur = queue.shift();
- if (cur) {
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
- if (cur?.left !== null) queue.push(cur.left);
- if (cur?.right !== null) queue.push(cur.right);
- }
- }
-
- return this._getResultByPropertyName(nodeOrPropertyName);
- }
-
- /**
- * Performs a depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
- * @returns An array of binary tree node IDs.
- */
- dfs(): BinaryTreeNodeKey[];
-
- /**
- * Performs a depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @returns An array of values corresponding to the specified property.
- */
- dfs(pattern: DFSOrderPattern): BinaryTreeNodeKey[];
-
- /**
- * Performs a depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {string} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of values corresponding to the specified property.
- */
- dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
-
- /**
- * Performs a depth-first search (dfs) traversal on a binary tree and accumulates the 'val' property of each node.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of 'val' properties from each node.
- */
- dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N[];
-
- /**
- * Performs a depth-first search (dfs) traversal on a binary tree and accumulates nodes themselves.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of binary tree nodes.
- */
- dfs(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
-
- /**
- * The dfs function performs a depth-first search traversal on a binary tree and returns the accumulated properties of
- * each node based on the specified pattern and property name.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The name of a property of the nodes in the binary tree. This property will be used to accumulate values during the depth-first search traversal. If no `nodeOrPropertyName` is provided, the default value is `'key'`.
- * @returns an instance of the BinaryTreeNodeProperties class, which contains the accumulated properties of the binary tree nodes based on the specified pattern and node or property name.
- */
- dfs(pattern: DFSOrderPattern = 'in', nodeOrPropertyName: NodeOrPropertyName = 'key'): BinaryTreeNodeProperties {
- this._clearResults();
- const _traverse = (node: N) => {
- switch (pattern) {
- case 'in':
- if (node.left) _traverse(node.left);
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
- if (node.right) _traverse(node.right);
- break;
- case 'pre':
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
- if (node.left) _traverse(node.left);
- if (node.right) _traverse(node.right);
- break;
- case 'post':
- if (node.left) _traverse(node.left);
- if (node.right) _traverse(node.right);
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
- break;
- }
- };
-
- this.root && _traverse(this.root);
- return this._getResultByPropertyName(nodeOrPropertyName);
- }
-
- // --- start additional methods ---
-
- /**
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
- * @returns An array of binary tree node IDs.
- */
- dfsIterative(): BinaryTreeNodeKey[];
-
- /**
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on their 'key' property.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @returns An array of values corresponding to the specified property.
- */
- dfsIterative(pattern: DFSOrderPattern): BinaryTreeNodeKey[];
-
- /**
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates properties of each node based on the specified property name.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {string} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of values corresponding to the specified property.
- */
- dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
-
- /**
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates the 'val' property of each node.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of 'val' properties from each node.
- */
- dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N['val'][];
-
- /**
- * Performs an iterative depth-first search (dfs) traversal on a binary tree and accumulates nodes themselves.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of binary tree nodes.
- */
- dfsIterative(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
-
- /**
- * The dfsIterative function performs an iterative depth-first search traversal on a binary tree, with the option to
- * specify the traversal pattern and the property name to accumulate results by.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The name of a property of the nodes in the binary tree. This property will be used to accumulate values during the depth-first search traversal. By default, it is set to `'key'`.
- * @returns An object of type BinaryTreeNodeProperties.
- */
- dfsIterative(
+ dfs>(
+ callback: C = ((node: N) => node.key) as C,
pattern: DFSOrderPattern = 'in',
- nodeOrPropertyName: NodeOrPropertyName = 'key'
- ): BinaryTreeNodeProperties {
- this._clearResults();
- if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
- // 0: visit, 1: print
- const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: this.root}];
-
- while (stack.length > 0) {
- const cur = stack.pop();
- if (!cur || !cur.node) continue;
- if (cur.opt === 1) {
- this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
- } else {
+ beginRoot: N | null = this.root,
+ iterationType: IterationType = IterationType.ITERATIVE
+ ): ReturnType[] {
+ if (!beginRoot) return [];
+ const ans: ReturnType>[] = [];
+ if (iterationType === IterationType.RECURSIVE) {
+ const _traverse = (node: N) => {
switch (pattern) {
case 'in':
- stack.push({opt: 0, node: cur.node.right});
- stack.push({opt: 1, node: cur.node});
- stack.push({opt: 0, node: cur.node.left});
+ if (node.left) _traverse(node.left);
+ ans.push(callback(node));
+ if (node.right) _traverse(node.right);
break;
case 'pre':
- stack.push({opt: 0, node: cur.node.right});
- stack.push({opt: 0, node: cur.node.left});
- stack.push({opt: 1, node: cur.node});
+ ans.push(callback(node));
+
+ if (node.left) _traverse(node.left);
+ if (node.right) _traverse(node.right);
break;
case 'post':
- stack.push({opt: 1, node: cur.node});
- stack.push({opt: 0, node: cur.node.right});
- stack.push({opt: 0, node: cur.node.left});
- break;
- default:
- stack.push({opt: 0, node: cur.node.right});
- stack.push({opt: 1, node: cur.node});
- stack.push({opt: 0, node: cur.node.left});
+ if (node.left) _traverse(node.left);
+ if (node.right) _traverse(node.right);
+ ans.push(callback(node));
+
break;
}
+ };
+
+ _traverse(beginRoot);
+ } else {
+ // 0: visit, 1: print
+ const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{opt: 0, node: beginRoot}];
+
+ while (stack.length > 0) {
+ const cur = stack.pop();
+ if (!cur || !cur.node) continue;
+ if (cur.opt === 1) {
+ ans.push(callback(cur.node));
+ } else {
+ switch (pattern) {
+ case 'in':
+ stack.push({opt: 0, node: cur.node.right});
+ stack.push({opt: 1, node: cur.node});
+ stack.push({opt: 0, node: cur.node.left});
+ break;
+ case 'pre':
+ stack.push({opt: 0, node: cur.node.right});
+ stack.push({opt: 0, node: cur.node.left});
+ stack.push({opt: 1, node: cur.node});
+ break;
+ case 'post':
+ stack.push({opt: 1, node: cur.node});
+ stack.push({opt: 0, node: cur.node.right});
+ stack.push({opt: 0, node: cur.node.left});
+ break;
+ default:
+ stack.push({opt: 0, node: cur.node.right});
+ stack.push({opt: 1, node: cur.node});
+ stack.push({opt: 0, node: cur.node.left});
+ break;
+ }
+ }
}
}
- return this._getResultByPropertyName(nodeOrPropertyName);
+ return ans;
}
/**
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on their 'key' property.
- * @returns An array of binary tree node IDs.
+ * The bfs function performs a breadth-first search traversal on a binary tree, executing a callback
+ * function on each node.
+ * @param callback - The `callback` parameter is a function that will be called for each node in the
+ * breadth-first search. It takes a node of type `N` as its argument and returns a value of type
+ * `ReturnType>`. The default value for this parameter is `((node: N) => node.key)
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
+ * search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
+ * will not be performed and an empty array will be returned.
+ * @param iterationType - The `iterationType` parameter determines the type of iteration to be used
+ * in the breadth-first search (BFS) algorithm. It can have two possible values:
+ * @returns The function `bfs` returns an array of `ReturnType>[]`.
*/
- levelIterative(): BinaryTreeNodeKey[];
+ bfs>(
+ callback: C = ((node: N) => node.key) as C,
+ beginRoot: N | null = this.root,
+ iterationType = this.iterationType
+ ): ReturnType[] {
+ if (!beginRoot) return [];
- /**
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on their 'key' property.
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
- * @returns An array of binary tree node IDs.
- */
- levelIterative(node: N | null): BinaryTreeNodeKey[];
+ const ans: ReturnType>[] = [];
- /**
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates properties of each node based on the specified property name.
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
- * @param {string} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of values corresponding to the specified property.
- */
- levelIterative(node: N | null, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
+ if (iterationType === IterationType.RECURSIVE) {
+ const queue = new Queue([beginRoot]);
- /**
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates the 'val' property of each node.
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
- * @param {'val'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of 'val' properties from each node.
- */
- levelIterative(node: N | null, nodeOrPropertyName: 'val'): N['val'][];
+ function traverse(level: number) {
+ if (queue.size === 0) return;
- /**
- * Performs a level-order traversal on a binary tree starting from the specified node and accumulates nodes themselves.
- * @param {N | null} node - The starting node for the level order traversal. If null, the root node of the tree is used as the starting node.
- * @param {'node'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of binary tree nodes.
- */
- levelIterative(node: N | null, nodeOrPropertyName: 'node'): N[];
+ const current = queue.shift()!;
+ ans.push(callback(current));
- /**
- * The `levelIterative` function performs a level-order traversal on a binary tree and returns the values of the nodes
- * in an array, based on a specified property name.
- * @param {N | null} node - The `node` parameter is a BinaryTreeNode object representing the starting
- * node for the level order traversal. It can be null if no specific node is provided, in which case the root node of
- * the tree is used as the starting node.
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that
- * can be either a `BinaryTreeNode` property name or the string `'key'`. If a property name is provided, the function
- * will accumulate results based on that property. If no property name is provided, the function will default to
- * accumulating results based on the 'key' property.
- * @returns An object of type `BinaryTreeNodeProperties`.
- */
- levelIterative(
- node: N | null = this.root,
- nodeOrPropertyName: NodeOrPropertyName = 'key'
- ): BinaryTreeNodeProperties {
- if (!node) return [];
+ if (current.left) queue.push(current.left);
+ if (current.right) queue.push(current.right);
- this._clearResults();
- const queue: N[] = [node];
+ traverse(level + 1);
+ }
- while (queue.length > 0) {
- const cur = queue.shift();
- if (cur) {
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
- if (cur.left) {
- queue.push(cur.left);
- }
- if (cur.right) {
- queue.push(cur.right);
+ traverse(0);
+ } else {
+ const queue = new Queue([beginRoot]);
+ while (queue.size > 0) {
+ const levelSize = queue.size;
+
+ for (let i = 0; i < levelSize; i++) {
+ const current = queue.shift()!;
+ ans.push(callback(current));
+
+ if (current.left) queue.push(current.left);
+ if (current.right) queue.push(current.right);
}
}
}
-
- return this._getResultByPropertyName(nodeOrPropertyName);
+ return ans;
}
/**
- * Collects nodes from a binary tree by a specified property and organizes them into levels.
- * @returns A 2D array of AbstractBinaryTreeNodeProperty objects.
+ * The `listLevels` function takes a binary tree node and a callback function, and returns an array
+ * of arrays representing the levels of the tree.
+ * @param {C} callback - The `callback` parameter is a function that will be called on each node in
+ * the tree. It takes a node as input and returns a value. The return type of the callback function
+ * is determined by the generic type `C`.
+ * @param {N | null} beginRoot - The `beginRoot` parameter represents the starting node of the binary tree
+ * traversal. It can be any node in the binary tree. If no node is provided, the traversal will start
+ * from the root node of the binary tree.
+ * @param iterationType - The `iterationType` parameter determines whether the tree traversal is done
+ * recursively or iteratively. It can have two possible values:
+ * @returns The function `listLevels` returns an array of arrays, where each inner array represents a
+ * level in a binary tree. Each inner array contains the return type of the provided callback
+ * function `C` applied to the nodes at that level.
*/
- listLevels(): BinaryTreeNodeKey[][];
+ listLevels>(
+ callback: C = ((node: N) => node.key) as C,
+ beginRoot: N | null = this.root,
+ iterationType = this.iterationType
+ ): ReturnType[][] {
+ if (!beginRoot) return [];
+ const levelsNodes: ReturnType[][] = [];
- /**
- * Collects nodes from a binary tree by a specified property and organizes them into levels.
- * @param {N | null} node - The root node of the binary tree or null. If null, the function will use the root node of the current binary tree instance.
- * @returns A 2D array of AbstractBinaryTreeNodeProperty objects.
- */
- listLevels(node: N | null): BinaryTreeNodeKey[][];
-
- /**
- * Collects nodes from a binary tree by a specified property and organizes them into levels.
- * @param {N | null} node - The root node of the binary tree or null. If null, the function will use the root node of the current binary tree instance.
- * @param {'key} nodeOrPropertyName - The property of the BinaryTreeNode object to collect at each level.
- * @returns A 2D array of values corresponding to the specified property.
- */
- listLevels(node: N | null, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[][];
-
- /**
- * Collects nodes from a binary tree by a specified property and organizes them into levels.
- * @param {N | null} node - The root node of the binary tree or null. If null, the function will use the root node of the current binary tree instance.
- * @param {'val'} nodeOrPropertyName - The property of the BinaryTreeNode object to collect at each level.
- * @returns A 2D array of 'val' properties from each node.
- */
- listLevels(node: N | null, nodeOrPropertyName: 'val'): N['val'][][];
-
- /**
- * Collects nodes from a binary tree by a specified property and organizes them into levels.
- * @param {N | null} node - The root node of the binary tree or null. If null, the function will use the root node of the current binary tree instance.
- * @param {'node'} nodeOrPropertyName - The property of the BinaryTreeNode object to collect at each level.
- * @returns A 2D array of binary tree nodes.
- */
- listLevels(node: N | null, nodeOrPropertyName: 'node'): N[][];
-
- /**
- * The `listLevels` function collects nodes from a binary tree by a specified property and organizes them into levels.
- * @param {N | null} node - The `node` parameter is a BinaryTreeNode object or null. It represents the root node of a binary tree. If it is null, the function will use the root node of the current binary tree instance.
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that specifies the property of the `BinaryTreeNode` object to collect at each level. It can be one of the following values: 'key', 'val', or 'node'. If not provided, it defaults to 'key'.
- * @returns A 2D array of `AbstractBinaryTreeNodeProperty` objects.
- */
- listLevels(
- node: N | null = this.root,
- nodeOrPropertyName: NodeOrPropertyName = 'key'
- ): BinaryTreeNodeProperty[][] {
- if (!node) return [];
-
- const levelsNodes: BinaryTreeNodeProperty[][] = [];
-
- const collectByProperty = (node: N, level: number) => {
- switch (nodeOrPropertyName) {
- case 'key':
- levelsNodes[level].push(node.key);
- break;
- case 'val':
- levelsNodes[level].push(node.val);
- break;
- case 'node':
- levelsNodes[level].push(node);
- break;
- default:
- levelsNodes[level].push(node.key);
- break;
- }
- };
-
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _recursive = (node: N, level: number) => {
if (!levelsNodes[level]) levelsNodes[level] = [];
- collectByProperty(node, level);
+ levelsNodes[level].push(callback(node));
if (node.left) _recursive(node.left, level + 1);
if (node.right) _recursive(node.right, level + 1);
};
- _recursive(node, 0);
+ _recursive(beginRoot, 0);
} else {
- const stack: [N, number][] = [[node, 0]];
+ const stack: [N, number][] = [[beginRoot, 0]];
while (stack.length > 0) {
const head = stack.pop()!;
const [node, level] = head;
if (!levelsNodes[level]) levelsNodes[level] = [];
- collectByProperty(node, level);
+ levelsNodes[level].push(callback(node));
if (node.right) stack.push([node.right, level + 1]);
if (node.left) stack.push([node.left, level + 1]);
}
@@ -1242,9 +1030,9 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The function returns the predecessor of a given node in a binary tree.
- * @param node - The parameter `node` is a BinaryTreeNode object, representing a node in a binary tree.
- * @returns the predecessor of the given node in a binary tree.
+ * The function returns the predecessor node of a given node in a binary tree.
+ * @param {N} node - The parameter "node" represents a node in a binary tree.
+ * @returns The function `getPredecessor` returns the predecessor node of the given node `node`.
*/
getPredecessor(node: N): N {
if (node.left) {
@@ -1260,60 +1048,31 @@ export class BinaryTree = BinaryTreeNode>
}
}
- /**
- * Time complexity is O(n)
- * Space complexity of Iterative dfs equals to recursive dfs which is O(n) because of the stack
- */
+ // --- start additional methods ---
/**
- * Performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris traversal algorithm.
- * @returns An array of binary tree node IDs.
+ * The `morris` function performs a depth-first traversal of a binary tree using the Morris traversal
+ * algorithm and returns an array of values obtained by applying a callback function to each node.
+ * @param callback - The `callback` parameter is a function that will be called on each node in the
+ * tree. It takes a node of type `N` as input and returns a value of type `ReturnType>`. The
+ * default value for this parameter is `((node: N) => node.key)`.
+ * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
+ * determines the order in which the nodes of a binary tree are traversed. It can have one of the
+ * following values:
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the Morris
+ * traversal. It specifies the root node of the tree from which the traversal should begin. If
+ * `beginRoot` is `null`, an empty array will be returned.
+ * @returns The `morris` function returns an array of `ReturnType>` values.
*/
- morris(): BinaryTreeNodeKey[];
+ morris>(
+ callback: C = ((node: N) => node.key) as C,
+ pattern: DFSOrderPattern = 'in',
+ beginRoot: N | null = this.root
+ ): ReturnType[] {
+ if (beginRoot === null) return [];
+ const ans: ReturnType>[] = [];
- /**
- * Performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris traversal algorithm and accumulates properties of each node based on the specified property name.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'key'} nodeOrPropertyName - The name of the property to accumulate.
- * @returns An array of values corresponding to the specified property.
- */
- morris(pattern: DFSOrderPattern, nodeOrPropertyName: 'key'): BinaryTreeNodeKey[];
-
- /**
- * Performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris traversal algorithm and accumulates properties of each node based on the specified property name.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @returns An array of values corresponding to the specified property.
- */
- morris(pattern: DFSOrderPattern): BinaryTreeNodeKey[];
-
- /**
- * Performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris traversal algorithm and accumulates the 'val' property of each node.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'val'} nodeOrPropertyName - The property of the BinaryTreeNode object to collect at each level.
- * @returns An array of 'val' properties from each node.
- */
- morris(pattern: DFSOrderPattern, nodeOrPropertyName: 'val'): N[];
-
- /**
- * Performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris traversal algorithm and accumulates nodes themselves.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {'node'} nodeOrPropertyName - The property of the BinaryTreeNode object to collect at each level.
- * @returns An array of binary tree nodes.
- */
- morris(pattern: DFSOrderPattern, nodeOrPropertyName: 'node'): N[];
-
- /**
- * The `morris` function performs an in-order, pre-order, or post-order traversal on a binary tree using the Morris traversal algorithm.
- * @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The property name of the nodes to retrieve or perform operations on during the traversal. It can be any valid property name of the nodes in the binary tree. If not provided, it defaults to 'key'.
- * @returns An array of BinaryTreeNodeProperties objects.
- */
- morris(pattern: DFSOrderPattern = 'in', nodeOrPropertyName: NodeOrPropertyName = 'key'): BinaryTreeNodeProperties {
- if (this.root === null) return [];
-
- this._clearResults();
-
- let cur: N | null | undefined = this.root;
+ let cur: N | null | undefined = beginRoot;
const _reverseEdge = (node: N | null | undefined) => {
let pre: N | null | undefined = null;
let next: N | null | undefined = null;
@@ -1329,7 +1088,7 @@ export class BinaryTree = BinaryTreeNode>
const tail: N | null | undefined = _reverseEdge(node);
let cur: N | null | undefined = tail;
while (cur) {
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
+ ans.push(callback(cur));
cur = cur.right;
}
_reverseEdge(tail);
@@ -1347,7 +1106,7 @@ export class BinaryTree = BinaryTreeNode>
predecessor.right = null;
}
}
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
+ ans.push(callback(cur));
cur = cur.right;
}
break;
@@ -1357,14 +1116,14 @@ export class BinaryTree = BinaryTreeNode>
const predecessor = this.getPredecessor(cur);
if (!predecessor.right) {
predecessor.right = cur;
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
+ ans.push(callback(cur));
cur = cur.left;
continue;
} else {
predecessor.right = null;
}
} else {
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
+ ans.push(callback(cur));
}
cur = cur.right;
}
@@ -1384,22 +1143,83 @@ export class BinaryTree = BinaryTreeNode>
}
cur = cur.right;
}
- _printEdge(this.root);
+ _printEdge(beginRoot);
break;
}
-
- return this._getResultByPropertyName(nodeOrPropertyName);
+ return ans;
}
/**
- * The function adds a new node to a binary tree if there is an available position.
- * @param {N | null} newNode - The `newNode` parameter is of type `N | null`, which means it can either be a node of
- * type `N` or `null`. It represents the node that you want to add to the binary tree.
- * @param {N} parent - The parent parameter is of type N, which represents a node in a binary tree.
- * @returns either the left or right child node of the parent node, depending on which child is available for adding
- * the new node. If a new node is added, the function also updates the size of the binary tree. If neither the left nor
- * right child is available, the function returns undefined. If the parent node is null, the function also returns
- * undefined.
+ * The above function is an iterator for a binary tree that can be used to traverse the tree in
+ * either an iterative or recursive manner.
+ * @param node - The `node` parameter represents the current node in the binary tree from which the
+ * iteration starts. It is an optional parameter with a default value of `this.root`, which means
+ * that if no node is provided, the iteration will start from the root of the binary tree.
+ * @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
+ * binary tree nodes in a specific order.
+ */
+ * [Symbol.iterator](node = this.root): Generator {
+ if (!node) {
+ return;
+ }
+
+ if (this.iterationType === IterationType.ITERATIVE) {
+ const stack: (N | null | undefined)[] = [];
+ let current: N | null | undefined = node;
+
+ while (current || stack.length > 0) {
+ while (current) {
+ stack.push(current);
+ current = current.left;
+ }
+
+ current = stack.pop();
+
+ if (current) yield current.key;
+ if (current) current = current.right;
+ }
+ } else {
+ if (node.left) {
+ yield* this[Symbol.iterator](node.left);
+ }
+ yield node.key;
+ if (node.right) {
+ yield* this[Symbol.iterator](node.right);
+ }
+ }
+ }
+
+ /**
+ * Swap the data of two nodes in the binary tree.
+ * @param {N} srcNode - The source node to swap.
+ * @param {N} destNode - The destination node to swap.
+ * @returns {N} - The destination node after the swap.
+ */
+ protected _swap(srcNode: N, destNode: N): N {
+ const {key, value} = destNode;
+ const tempNode = this.createNode(key, value);
+
+ if (tempNode) {
+ destNode.key = srcNode.key;
+ destNode.value = srcNode.value;
+
+ srcNode.key = tempNode.key;
+ srcNode.value = tempNode.value;
+ }
+
+ return destNode;
+ }
+
+ /**
+ * The function `_addTo` adds a new node to a binary tree if there is an available position.
+ * @param {N | null} newNode - The `newNode` parameter represents the node that you want to add to
+ * the binary tree. It can be either a node object or `null`.
+ * @param {N} parent - The `parent` parameter represents the parent node to which the new node will
+ * be added as a child.
+ * @returns either the left or right child node of the parent node, depending on which child is
+ * available for adding the new node. If a new node is added, the function also updates the size of
+ * the binary tree. If neither the left nor right child is available, the function returns undefined.
+ * If the parent node is null, the function also returns undefined.
*/
protected _addTo(newNode: N | null, parent: N): N | null | undefined {
if (parent) {
@@ -1408,13 +1228,13 @@ export class BinaryTree = BinaryTreeNode>
if (parent.left === undefined) {
parent.left = newNode;
if (newNode) {
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
}
return parent.left;
} else if (parent.right === undefined) {
parent.right = newNode;
if (newNode) {
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
}
return parent.right;
} else {
@@ -1426,17 +1246,10 @@ export class BinaryTree = BinaryTreeNode>
}
/**
- * The function sets the loop type for a protected variable.
- * @param {LoopType} value - The value parameter is of type LoopType.
- */
- protected _setLoopType(value: LoopType) {
- this._loopType = value;
- }
-
- /**
- * The function sets the root property of an object to a given value, and if the value is not null, it also sets the
- * parent property of the value to undefined.
- * @param {N | null} v - The parameter `v` is of type `N | null`, which means it can either be of type `N` or `null`.
+ * The function sets the root property of an object to a given value, and if the value is not null,
+ * it also sets the parent property of the value to undefined.
+ * @param {N | null} v - The parameter `v` is of type `N | null`, which means it can either be of
+ * type `N` or `null`.
*/
protected _setRoot(v: N | null) {
if (v) {
@@ -1445,116 +1258,5 @@ export class BinaryTree = BinaryTreeNode>
this._root = v;
}
- /**
- * The function sets the size of a protected variable.
- * @param {number} v - number
- */
- protected _setSize(v: number) {
- this._size = v;
- }
-
- /**
- * The function `_clearResults` resets the values of several arrays used for tracking visited nodes and their
- * properties.
- */
- protected _clearResults() {
- this.visitedKey = [];
- this.visitedVal = [];
- this.visitedNode = [];
- }
-
- /**
- * The function checks if a given property of a binary tree node matches a specified value, and if so, adds the node to
- * a result array.
- * @param {N} cur - The current node being processed.
- * @param {(N | null | undefined)[]} result - An array that stores the matching nodes.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter is either a `BinaryTreeNodeKey` or a `N`
- * type. It represents the property value that we are comparing against in the switch statement.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name to compare against when pushing nodes into the `result` array. It can be either `'key'`
- * or `'val'`. If it is not provided or is not equal to `'key'` or `'val'`, the
- * @param {boolean} [onlyOne] - The `onlyOne` parameter is an optional boolean parameter that determines whether to
- * stop after finding the first matching node or continue searching for all matching nodes. If `onlyOne` is set to
- * `true`, the function will stop after finding the first matching node and return `true`. If `onlyOne
- * @returns a boolean value indicating whether only one matching node should be pushed into the result array.
- */
- protected _pushByPropertyNameStopOrNot(
- cur: N,
- result: (N | null | undefined)[],
- nodeProperty: BinaryTreeNodeKey | N,
- propertyName: BinaryTreeNodePropertyName = 'key',
- onlyOne = false
- ) {
- switch (propertyName) {
- case 'key':
- if (cur.key === nodeProperty) {
- result.push(cur);
- return onlyOne;
- }
- break;
- case 'val':
- if (cur.val === nodeProperty) {
- result.push(cur);
- return onlyOne;
- }
- break;
- default:
- if (cur.key === nodeProperty) {
- result.push(cur);
- return onlyOne;
- }
- break;
- }
- }
-
- /**
- * The function `_accumulatedByPropertyName` accumulates values from a given node based on the specified property name.
- * @param {N} node - The `node` parameter is of type `N`, which represents a node in a data structure.
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that
- * can be either a string representing a property name or a reference to a `Node` object. If it is a string, it
- * specifies the property name to be used for accumulating values. If it is a `Node` object, it specifies
- */
- protected _accumulatedByPropertyName(node: N, nodeOrPropertyName: NodeOrPropertyName = 'key') {
- switch (nodeOrPropertyName) {
- case 'key':
- this.visitedKey.push(node.key);
- break;
- case 'val':
- this.visitedVal.push(node.val);
- break;
- case 'node':
- this.visitedNode.push(node);
- break;
- default:
- this.visitedKey.push(node.key);
- break;
- }
- }
-
- /**
- * The time complexity of Morris traversal is O(n), it may slower than others
- * The space complexity Morris traversal is O(1) because no using stack
- */
-
- /**
- * The function `_getResultByPropertyName` returns the corresponding property value based on the given node or property
- * name.
- * @param {NodeOrPropertyName} [nodeOrPropertyName] - The parameter `nodeOrPropertyName` is an optional parameter that
- * can accept either a `NodeOrPropertyName` type or be undefined.
- * @returns The method `_getResultByPropertyName` returns an instance of `BinaryTreeNodeProperties`.
- */
- protected _getResultByPropertyName(nodeOrPropertyName: NodeOrPropertyName = 'key'): BinaryTreeNodeProperties {
- switch (nodeOrPropertyName) {
- case 'key':
- return this.visitedKey;
- case 'val':
- return this.visitedVal;
- case 'node':
- return this.visitedNode;
- default:
- return this.visitedKey;
- }
- }
-
// --- end additional methods ---
}
diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts
index 1c0a51d..94cd873 100644
--- a/src/data-structures/binary-tree/bst.ts
+++ b/src/data-structures/binary-tree/bst.ts
@@ -5,27 +5,26 @@
* @copyright Copyright (c) 2022 Tyler Zeng
* @license MIT License
*/
-import type {
- BinaryTreeNodeKey,
- BinaryTreeNodePropertyName,
- BSTComparator,
- BSTNodeNested,
- BSTOptions
-} from '../../types';
-import {CP, LoopType} from '../../types';
+import type {BSTComparator, BSTNodeNested, BSTOptions, BTNCallback, BTNKey} from '../../types';
+import {CP, IterationType} from '../../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree} from '../../interfaces';
+import {Queue} from '../queue';
-export class BSTNode = BSTNodeNested> extends BinaryTreeNode {
- constructor(key: BinaryTreeNodeKey, val?: V) {
- super(key, val);
+export class BSTNode = BSTNodeNested> extends BinaryTreeNode {
+ constructor(key: BTNKey, value?: V) {
+ super(key, value);
}
}
-export class BST = BSTNode> extends BinaryTree implements IBinaryTree {
+export class BST = BSTNode>>
+ extends BinaryTree
+ implements IBinaryTree {
/**
- * The constructor function initializes a binary search tree object with an optional comparator function.
- * @param {BSTOptions} [options] - An optional object that contains configuration options for the binary search tree.
+ * The constructor function initializes a binary search tree object with an optional comparator
+ * function.
+ * @param {BSTOptions} [options] - An optional object that contains configuration options for the
+ * binary search tree.
*/
constructor(options?: BSTOptions) {
super(options);
@@ -39,39 +38,40 @@ export class BST = BSTNode> extends BinaryTree
/**
* The function creates a new binary search tree node with the given key and value.
- * @param {BinaryTreeNodeKey} key - The `key` parameter is the identifier for the binary tree node. It is used to uniquely
- * identify each node in the binary tree.
- * @param [val] - The `val` parameter is an optional value that can be assigned to the node. It represents the value
- * that will be stored in the node.
+ * @param {BTNKey} key - The key parameter is the key value that will be associated with
+ * the new node. It is used to determine the position of the node in the binary search tree.
+ * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It
+ * represents the value associated with the node in a binary search tree.
* @returns a new instance of the BSTNode class with the specified key and value.
*/
- override createNode(key: BinaryTreeNodeKey, val?: N['val']): N {
- return new BSTNode(key, val) as N;
+ override createNode(key: BTNKey, value?: V): N {
+ return new BSTNode(key, value) as N;
}
/**
- * The `add` function adds a new node to a binary search tree, either by creating a new node or by updating an existing
- * node with the same ID.
- * @param {BinaryTreeNodeKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a `BinaryTreeNodeKey` or a `N`
- * (which represents a binary tree node) or `null`.
- * @param [val] - The `val` parameter is an optional value that can be assigned to the `val` property of the new node
- * being added to the binary search tree.
- * @returns The function `add` returns the inserted node (`inserted`) which can be of type `N`, `null`, or `undefined`.
+ * The `add` function in a binary search tree class inserts a new node with a given key and value
+ * into the tree.
+ * @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
+ * `BTNKey` (which can be a number or a string), a `BSTNode` object, or `null`.
+ * @param [value] - The `value` parameter is the value to be assigned to the new node being added to the
+ * binary search tree.
+ * @returns the inserted node (N) if it was successfully added to the binary search tree. If the node
+ * was not added or if the parameters were invalid, it returns null or undefined.
*/
- override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined {
- // TODO support node as a param
+ override add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
+ // TODO support node as a parameter
let inserted: N | null = null;
let newNode: N | null = null;
if (keyOrNode instanceof BSTNode) {
newNode = keyOrNode;
} else if (typeof keyOrNode === 'number') {
- newNode = this.createNode(keyOrNode, val);
+ newNode = this.createNode(keyOrNode, value);
} else if (keyOrNode === null) {
newNode = null;
}
if (this.root === null) {
this._setRoot(newNode);
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
inserted = this.root;
} else {
let cur = this.root;
@@ -80,7 +80,7 @@ export class BST = BSTNode> extends BinaryTree
if (cur !== null && newNode !== null) {
if (this._compare(cur.key, newNode.key) === CP.eq) {
if (newNode) {
- cur.val = newNode.val;
+ cur.value = newNode.value;
}
//Duplicates are not accepted.
traversing = false;
@@ -93,7 +93,7 @@ export class BST = BSTNode> extends BinaryTree
}
//Add to the left of the current node
cur.left = newNode;
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
traversing = false;
inserted = cur.left;
} else {
@@ -108,7 +108,7 @@ export class BST = BSTNode> extends BinaryTree
}
//Add to the right of the current node
cur.right = newNode;
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
traversing = false;
inserted = cur.right;
} else {
@@ -125,41 +125,49 @@ export class BST = BSTNode> extends BinaryTree
}
/**
- * The `addMany` function overrides the base class method to add multiple nodes to a binary search tree in a balanced
- * manner.
- * @param {[BinaryTreeNodeKey | N , N['val']][]} keysOrNodes - The `keysOrNodes` parameter in the `addMany` function is an array of
- * `BinaryTreeNodeKey` or `N` (node) objects, or `null` values. It represents the nodes or node IDs that need to be added
- * to the binary search tree.
- * @param {N['val'][]} data - The values of tree nodes
+ * The `addMany` function is used to efficiently add multiple nodes to a binary search tree while
+ * maintaining balance.
+ * @param {[BTNKey | N, N['value']][]} keysOrNodes - The `arr` parameter in the `addMany` function
+ * represents an array of keys or nodes that need to be added to the binary search tree. It can be an
+ * array of `BTNKey` or `N` (which represents the node type in the binary search tree) or
+ * `null
+ * @param {V[]} data - The values of tree nodes
* @param {boolean} isBalanceAdd - If true the nodes will be balance inserted in binary search method.
- * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
+ * @param iterationType - The `iterationType` parameter determines the type of iteration to be used.
+ * It can have two possible values:
+ * @returns The `addMany` function returns an array of `N`, `null`, or `undefined` values.
*/
+
override addMany(
- keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
- data?: N['val'][],
- isBalanceAdd = false
+ keysOrNodes: (BTNKey | null)[] | (N | null)[],
+ data?: V[],
+ isBalanceAdd = true,
+ iterationType = this.iterationType
): (N | null | undefined)[] {
- function hasNoNull(arr: (BinaryTreeNodeKey | null)[] | (N | null)[]): arr is BinaryTreeNodeKey[] | N[] {
+ // TODO this addMany function is inefficient, it should be optimized
+ function hasNoNull(arr: (BTNKey | null)[] | (N | null)[]): arr is BTNKey[] | N[] {
return arr.indexOf(null) === -1;
}
+
if (!isBalanceAdd || !hasNoNull(keysOrNodes)) {
return super.addMany(keysOrNodes, data);
}
const inserted: (N | null | undefined)[] = [];
- const combinedArr: [BinaryTreeNodeKey | N, N['val']][] = keysOrNodes.map((value, index) => [value, data?.[index]]);
+ const combinedArr: [BTNKey | N, N['value']][] = keysOrNodes.map((value, index) => [value, data?.[index]]);
let sorted = [];
- function isNodeOrNullTuple(arr: [BinaryTreeNodeKey | N, N['val']][]): arr is [N, N['val']][] {
+
+ function isNodeOrNullTuple(arr: [BTNKey | N, N['value']][]): arr is [N, N['value']][] {
for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
return false;
}
- function isBinaryTreeKeyOrNullTuple(
- arr: [BinaryTreeNodeKey | N, N['val']][]
- ): arr is [BinaryTreeNodeKey, N['val']][] {
+
+ function isBinaryTreeKeyOrNullTuple(arr: [BTNKey | N, N['value']][]): arr is [BTNKey, N['value']][] {
for (const [keyOrNode] of arr) if (typeof keyOrNode === 'number') return true;
return false;
}
+
let sortedKeysOrNodes: (number | N | null)[] = [],
- sortedData: (N['val'] | undefined)[] | undefined = [];
+ sortedData: (V | undefined)[] | undefined = [];
if (isNodeOrNullTuple(combinedArr)) {
sorted = combinedArr.sort((a, b) => a[0].key - b[0].key);
@@ -169,8 +177,8 @@ export class BST = BSTNode> extends BinaryTree
throw new Error('Invalid input keysOrNodes');
}
sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
- sortedData = sorted.map(([, val]) => val);
- const recursive = (arr: (BinaryTreeNodeKey | null | N)[], data?: N['val'][]) => {
+ sortedData = sorted.map(([, value]) => value);
+ const recursive = (arr: (BTNKey | null | N)[], data?: (V | undefined)[]) => {
if (arr.length === 0) return;
const mid = Math.floor((arr.length - 1) / 2);
@@ -196,7 +204,7 @@ export class BST = BSTNode> extends BinaryTree
}
}
};
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
recursive(sortedKeysOrNodes, sortedData);
} else {
iterative();
@@ -206,73 +214,123 @@ export class BST = BSTNode> extends BinaryTree
}
/**
- * The function returns the first node in a binary tree that matches the given property name and value.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or a
- * generic type `N`. It represents the property of the binary tree node that you want to search for.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name to use for searching the binary tree nodes. If not provided, it defaults to `'key'`.
- * @returns The method is returning either a BinaryTreeNodeKey or N (generic type) or null.
+ * The function returns the first node in the binary tree that matches the given node property and
+ * callback.
+ * @param {ReturnType | N} identifier - The `nodeProperty` parameter is used to specify the
+ * property of the binary tree node that you want to search for. It can be either a specific key
+ * value (`BTNKey`) or a custom callback function (`BTNCallback`) that determines
+ * whether a node matches the desired property.
+ * @param callback - The `callback` parameter is a function that is used to determine whether a node
+ * matches the desired property. It takes a node as input and returns a boolean value indicating
+ * whether the node matches the property or not. If no callback function is provided, the default
+ * callback function `_defaultCallbackByKey` is used
+ * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
+ * the root node from which the search should begin.
+ * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
+ * be performed when searching for nodes in the binary tree. It can have one of the following values:
+ * @returns either the first node that matches the given nodeProperty and callback, or null if no
+ * matching node is found.
*/
+<<<<<<< HEAD
override get(nodeProperty: BinaryTreeNodeKey | N, propertyName: BinaryTreeNodePropertyName = 'key'): N | null {
return this.getNodes(nodeProperty, propertyName, true)[0] ?? undefined;
+=======
+ override get>(
+ identifier: ReturnType | null,
+ callback: C = ((node: N) => node.key) as C,
+ beginRoot = this.root,
+ iterationType = this.iterationType
+ ): N | null {
+ return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
+>>>>>>> 10bbcffcef4ed5901867431a3d3eae891d190b9d
}
/**
- * The function returns the key of the rightmost node if the comparison between two values is less than, the key of the
- * leftmost node if the comparison is greater than, and the key of the rightmost node otherwise.
- * @returns The method `lastKey()` returns the key of the rightmost node in the binary tree if the comparison between
- * the values at index 0 and 1 is less than, otherwise it returns the key of the leftmost node. If the comparison is
- * equal, it returns the key of the rightmost node. If there are no nodes in the tree, it returns 0.
+ * The function `lastKey` returns the key of the rightmost node if the comparison result is less
+ * than, the key of the leftmost node if the comparison result is greater than, and the key of the
+ * rightmost node otherwise.
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting point for finding the last
+ * key in a binary tree. It represents the root node of the subtree from which the search for the
+ * last key should begin. If no specific `beginRoot` is provided, the search will start from the root
+ * of the entire binary
+ * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
+ * be performed when finding the last key. It determines whether the iteration should be performed in
+ * pre-order, in-order, or post-order.
+ * @returns the key of the rightmost node in the binary tree if the comparison result is less than,
+ * the key of the leftmost node if the comparison result is greater than, and the key of the
+ * rightmost node otherwise. If no node is found, it returns 0.
*/
- lastKey(): BinaryTreeNodeKey {
- if (this._compare(0, 1) === CP.lt) return this.getRightMost()?.key ?? 0;
- else if (this._compare(0, 1) === CP.gt) return this.getLeftMost()?.key ?? 0;
- else return this.getRightMost()?.key ?? 0;
+ lastKey(beginRoot: N | null = this.root, iterationType = this.iterationType): BTNKey {
+ if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
+ else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
+ else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
}
/**
- * The function `getNodes` returns an array of nodes in a binary tree that match a given property value.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or an
- * `N` type. It represents the property of the binary tree node that you want to compare with.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name to use for comparison. If not provided, it defaults to `'key'`.
- * @param {boolean} [onlyOne] - The `onlyOne` parameter is an optional boolean parameter that determines whether to
- * return only one node that matches the given `nodeProperty` or all nodes that match the `nodeProperty`. If `onlyOne`
- * is set to `true`, the function will return an array with only one node (if
- * @returns an array of nodes (type N).
+ * The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
+ * using either recursive or iterative traversal.
+ * @param {ReturnType | N} identifier - The `nodeProperty` parameter represents the property
+ * of the binary tree node that you want to search for. It can be either a `BTNKey` or a
+ * generic type `N`.
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
+ * value. This value is compared with the `nodeProperty` parameter to determine if the node should be
+ * included in the result. The default value for `callback` is `((node: N) => node.key)`, which is
+ * a
+ * @param [onlyOne=false] - A boolean value indicating whether to stop the traversal after finding
+ * the first node that matches the nodeProperty. If set to true, the function will return an array
+ * containing only that node. If set to false (default), the function will continue the traversal and
+ * return an array containing all nodes that match the node
+ * @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the traversal. It
+ * specifies the root node of the binary tree from which the traversal should begin. If `beginRoot`
+ * is `null`, an empty array will be returned.
+ * @param iterationType - The `iterationType` parameter determines the type of iteration used to
+ * traverse the binary tree. It can have one of the following values:
+ * @returns an array of nodes (N[]).
*/
- override getNodes(
- nodeProperty: BinaryTreeNodeKey | N,
- propertyName: BinaryTreeNodePropertyName = 'key',
- onlyOne = false
+ override getNodes>(
+ identifier: ReturnType | null,
+ callback: C = ((node: N) => node.key) as C,
+ onlyOne = false,
+ beginRoot: N | null = this.root,
+ iterationType = this.iterationType
): N[] {
- if (!this.root) return [];
- const result: N[] = [];
+ if (!beginRoot) return [];
+ const ans: N[] = [];
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return;
+ const callbackResult = callback(cur);
+ if (callbackResult === identifier) {
+ ans.push(cur);
+ if (onlyOne) return;
+ }
if (!cur.left && !cur.right) return;
- if (propertyName === 'key') {
- if (this._compare(cur.key, nodeProperty as number) === CP.gt) cur.left && _traverse(cur.left);
- if (this._compare(cur.key, nodeProperty as number) === CP.lt) cur.right && _traverse(cur.right);
+ // TODO potential bug
+ if (callback === ((node: N) => node.key)) {
+ if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && _traverse(cur.left);
+ if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && _traverse(cur.right);
} else {
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
- _traverse(this.root);
+ _traverse(beginRoot);
} else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
+ const queue = new Queue([beginRoot]);
+ while (queue.size > 0) {
const cur = queue.shift();
if (cur) {
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return result;
- if (propertyName === 'key') {
- if (this._compare(cur.key, nodeProperty as number) === CP.gt) cur.left && queue.push(cur.left);
- if (this._compare(cur.key, nodeProperty as number) === CP.lt) cur.right && queue.push(cur.right);
+ const callbackResult = callback(cur);
+ if (callbackResult === identifier) {
+ ans.push(cur);
+ if (onlyOne) return ans;
+ }
+ // TODO potential bug
+ if (callback === ((node: N) => node.key)) {
+ if (this._compare(cur.key, identifier as number) === CP.gt) cur.left && queue.push(cur.left);
+ if (this._compare(cur.key, identifier as number) === CP.lt) cur.right && queue.push(cur.right);
} else {
cur.left && queue.push(cur.left);
cur.right && queue.push(cur.right);
@@ -281,140 +339,65 @@ export class BST = BSTNode> extends BinaryTree
}
}
- return result;
+ return ans;
}
// --- start additional functions
- /**
- * The `lesserSum` function calculates the sum of property values in a binary tree for nodes that have a property value
- * less than a given node.
- * @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name to use for calculating the sum. If not provided, it defaults to `'key'`.
- * @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in the
- * binary tree that have a lesser value than the specified `beginNode` based on the `propertyName`.
- */
- lesserSum(beginNode: N | BinaryTreeNodeKey | null, propertyName: BinaryTreeNodePropertyName = 'key'): number {
- if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'key');
- if (!beginNode) return 0;
- if (!this.root) return 0;
- const key = beginNode.key;
- const getSumByPropertyName = (cur: N) => {
- let needSum: number;
- switch (propertyName) {
- case 'key':
- needSum = cur.key;
- break;
- default:
- needSum = cur.key;
- break;
- }
- return needSum;
- };
-
- let sum = 0;
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N): void => {
- const compared = this._compare(cur.key, key);
- if (compared === CP.eq) {
- if (cur.right) sum += this.subTreeSum(cur.right, propertyName);
- return;
- } else if (compared === CP.lt) {
- if (cur.left) sum += this.subTreeSum(cur.left, propertyName);
- sum += getSumByPropertyName(cur);
- if (cur.right) _traverse(cur.right);
- else return;
- } else {
- if (cur.left) _traverse(cur.left);
- else return;
- }
- };
-
- _traverse(this.root);
- } else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
- const cur = queue.shift();
- if (cur) {
- const compared = this._compare(cur.key, key);
- if (compared === CP.eq) {
- if (cur.right) sum += this.subTreeSum(cur.right, propertyName);
- return sum;
- } else if (compared === CP.lt) {
- // todo maybe a bug
- if (cur.left) sum += this.subTreeSum(cur.left, propertyName);
- sum += getSumByPropertyName(cur);
- if (cur.right) queue.push(cur.right);
- else return sum;
- } else {
- if (cur.left) queue.push(cur.left);
- else return sum;
- }
- }
- }
- }
-
- return sum;
- }
/**
- * The `allGreaterNodesAdd` function adds a delta value to the specified property of all nodes in a binary tree that
- * have a greater value than a given node.
- * @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type),
- * `BinaryTreeNodeKey`, or `null`. It represents the node in the binary tree to which the delta value will be added.
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the property value of
- * each greater node should be increased.
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
- * specifies the property name of the nodes in the binary tree that you want to update. If not provided, it defaults to
- * 'key'.
- * @returns a boolean value.
+ * The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to
+ * nodes that have a key value lesser or greater than a target key value.
+ * @param callback - The `callback` parameter is a function that will be called for each node that
+ * meets the condition specified by the `lesserOrGreater` parameter. It takes a node as an argument
+ * and returns a value.
+ * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
+ * traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It can take one
+ * of the following values:
+ * @param {BTNKey | N | null} targetNode - The `targetNode` parameter in the
+ * `lesserOrGreaterTraverse` function is used to specify the node from which the traversal should
+ * start. It can be either a reference to a specific node (`N`), the key of a node
+ * (`BTNKey`), or `null` to
+ * @param iterationType - The `iterationType` parameter determines whether the traversal should be
+ * done recursively or iteratively. It can have two possible values:
+ * @returns The function `lesserOrGreaterTraverse` returns an array of `ReturnType>`.
*/
- allGreaterNodesAdd(
- node: N | BinaryTreeNodeKey | null,
- delta: number,
- propertyName: BinaryTreeNodePropertyName = 'key'
- ): boolean {
- if (typeof node === 'number') node = this.get(node, 'key');
- if (!node) return false;
- const key = node.key;
- if (!this.root) return false;
+ lesserOrGreaterTraverse>(
+ callback: C = ((node: N) => node.key) as C,
+ lesserOrGreater: CP = CP.lt,
+ targetNode: BTNKey | N | null = this.root,
+ iterationType = this.iterationType
+ ): ReturnType[] {
+ if (typeof targetNode === 'number') targetNode = this.get(targetNode);
+ const ans: ReturnType>[] = [];
+ if (!targetNode) return ans;
+ const targetKey = targetNode.key;
+ if (!this.root) return ans;
- const _sumByPropertyName = (cur: N) => {
- switch (propertyName) {
- case 'key':
- cur.key += delta;
- break;
- default:
- cur.key += delta;
- break;
- }
- };
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
- const compared = this._compare(cur.key, key);
- if (compared === CP.gt) _sumByPropertyName(cur);
+ const compared = this._compare(cur.key, targetKey);
+ if (compared === lesserOrGreater) ans.push(callback(cur));
if (!cur.left && !cur.right) return;
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) _traverse(cur.left);
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) _traverse(cur.right);
+ if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) _traverse(cur.left);
+ if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) _traverse(cur.right);
};
_traverse(this.root);
- return true;
+ return ans;
} else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
+ const queue = new Queue([this.root]);
+ while (queue.size > 0) {
const cur = queue.shift();
if (cur) {
- const compared = this._compare(cur.key, key);
- if (compared === CP.gt) _sumByPropertyName(cur);
+ const compared = this._compare(cur.key, targetKey);
+ if (compared === lesserOrGreater) ans.push(callback(cur));
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) queue.push(cur.left);
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) queue.push(cur.right);
+ if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) queue.push(cur.left);
+ if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) queue.push(cur.right);
}
}
- return true;
+ return ans;
}
}
@@ -429,22 +412,25 @@ export class BST = BSTNode> extends BinaryTree
*/
/**
- * The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
- * constructs a balanced binary search tree using either a recursive or iterative approach.
- * @returns The function `perfectlyBalance()` returns a boolean value.
+ * The `perfectlyBalance` function balances a binary search tree by adding nodes in a way that
+ * ensures the tree is perfectly balanced.
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
+ * type of iteration to use when building a balanced binary search tree. It can have two possible
+ * values:
+ * @returns The function `perfectlyBalance` returns a boolean value.
*/
- perfectlyBalance(): boolean {
- const sorted = this.dfs('in', 'node'),
+ perfectlyBalance(iterationType = this.iterationType): boolean {
+ const sorted = this.dfs(node => node, 'in'),
n = sorted.length;
this.clear();
if (sorted.length < 1) return false;
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const buildBalanceBST = (l: number, r: number) => {
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
- this.add(midNode.key, midNode.val);
+ this.add(midNode.key, midNode.value);
buildBalanceBST(l, m - 1);
buildBalanceBST(m + 1, r);
};
@@ -460,7 +446,7 @@ export class BST = BSTNode> extends BinaryTree
if (l <= r) {
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
- this.add(midNode.key, midNode.val);
+ this.add(midNode.key, midNode.value);
stack.push([m + 1, r]);
stack.push([l, m - 1]);
}
@@ -471,15 +457,17 @@ export class BST = BSTNode> extends BinaryTree
}
/**
- * The function `isAVLBalanced` checks if a binary tree is balanced according to the AVL tree property.
+ * The function checks if a binary tree is AVL balanced using either recursive or iterative approach.
+ * @param iterationType - The `iterationType` parameter is used to determine the method of iteration
+ * to check if the AVL tree is balanced. It can have two possible values:
* @returns a boolean value.
*/
- isAVLBalanced(): boolean {
+ isAVLBalanced(iterationType = this.iterationType): boolean {
if (!this.root) return true;
let balanced = true;
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const _height = (cur: N | null | undefined): number => {
if (!cur) return 0;
const leftHeight = _height(cur.left),
@@ -521,14 +509,14 @@ export class BST = BSTNode> extends BinaryTree
protected _comparator: BSTComparator = (a, b) => a - b;
/**
- * The function compares two binary tree node IDs using a comparator function and returns whether the first ID is
- * greater than, less than, or equal to the second ID.
- * @param {BinaryTreeNodeKey} a - "a" is a BinaryTreeNodeKey, which represents the identifier of a binary tree node.
- * @param {BinaryTreeNodeKey} b - The parameter "b" in the above code refers to a BinaryTreeNodeKey.
- * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater than), CP.lt (less
- * than), or CP.eq (equal).
+ * The function compares two values using a comparator function and returns whether the first value
+ * is greater than, less than, or equal to the second value.
+ * @param {BTNKey} a - The parameter "a" is of type BTNKey.
+ * @param {BTNKey} b - The parameter "b" in the above code represents a BTNKey.
+ * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
+ * than), CP.lt (less than), or CP.eq (equal).
*/
- protected _compare(a: BinaryTreeNodeKey, b: BinaryTreeNodeKey): CP {
+ protected _compare(a: BTNKey, b: BTNKey): CP {
const compared = this._comparator(a, b);
if (compared > 0) return CP.gt;
else if (compared < 0) return CP.lt;
diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts
index 3ba36c6..7d4c6c1 100644
--- a/src/data-structures/binary-tree/rb-tree.ts
+++ b/src/data-structures/binary-tree/rb-tree.ts
@@ -1,36 +1,33 @@
+<<<<<<< HEAD
import {BinaryTreeDeletedResult, BinaryTreeNodeKey, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../types';
+=======
+import {BTNKey, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../types';
+>>>>>>> 10bbcffcef4ed5901867431a3d3eae891d190b9d
import {IBinaryTree} from '../../interfaces';
import {BST, BSTNode} from './bst';
-export class RBTreeNode = RBTreeNodeNested> extends BSTNode<
- V,
- FAMILY
-> {
- private _color: RBColor;
-
- constructor(key: BinaryTreeNodeKey, val?: V) {
- super(key, val);
- this._color = RBColor.RED;
+export class RBTreeNode = RBTreeNodeNested> extends BSTNode {
+ constructor(key: BTNKey, value?: V) {
+ super(key, value);
+ this.color = RBColor.RED;
}
- get color(): RBColor {
- return this._color;
- }
+ color: RBColor;
- set color(value: RBColor) {
- this._color = value;
- }
}
-export class RBTree = RBTreeNode> extends BST implements IBinaryTree {
+export class RBTree = RBTreeNode>>
+ extends BST
+ implements IBinaryTree {
constructor(options?: RBTreeOptions) {
super(options);
}
- override createNode(key: BinaryTreeNodeKey, val?: N['val']): N {
- return new RBTreeNode(key, val) as N;
+ override createNode(key: BTNKey, value?: V): N {
+ return new RBTreeNode(key, value) as N;
}
+<<<<<<< HEAD
override add(key: BinaryTreeNodeKey, val?: N['val']): N {
const newNode = this.createNode(key, val);
if (!this.root) {
@@ -340,4 +337,338 @@ export class RBTree = RBTreeNode> extends BST<
return 0;
}
}
+=======
+ // override add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
+ // const inserted = super.add(keyOrNode, value);
+ // if (inserted) this._fixInsertViolation(inserted);
+ // return inserted;
+ // }
+ //
+ // // Method for fixing insert violations in a red-black tree
+ // protected _fixInsertViolation(node: N) {
+ // while (node !== this.root! && node.color === RBColor.RED && node.parent!.color === RBColor.RED) {
+ // const parent = node.parent!;
+ // const grandparent = parent.parent!;
+ // let uncle: N | null | undefined = null;
+ //
+ // if (parent === grandparent.left) {
+ // uncle = grandparent.right;
+ //
+ // // Case 1: The uncle node is red
+ // if (uncle && uncle.color === RBColor.RED) {
+ // grandparent.color = RBColor.RED;
+ // parent.color = RBColor.BLACK;
+ // uncle.color = RBColor.BLACK;
+ // node = grandparent;
+ // } else {
+ // // Case 2: The uncle node is black, and the current node is a right child
+ // if (node === parent.right) {
+ // this._rotateLeft(parent);
+ // node = parent;
+ // // Update parent reference
+ // node.parent = grandparent;
+ // parent.parent = node;
+ // }
+ //
+ // // Case 3: The uncle node is black, and the current node is a left child
+ // parent.color = RBColor.BLACK;
+ // grandparent.color = RBColor.RED;
+ // this._rotateRight(grandparent);
+ // }
+ // } else {
+ // // Symmetric case: The parent is the right child of the grandparent
+ // uncle = grandparent.left;
+ //
+ // // Case 1: The uncle node is red
+ // if (uncle && uncle.color === RBColor.RED) {
+ // grandparent.color = RBColor.RED;
+ // parent.color = RBColor.BLACK;
+ // uncle.color = RBColor.BLACK;
+ // node = grandparent;
+ // } else {
+ // // Case 2: The uncle node is black, and the current node is a left child
+ // if (node === parent.left) {
+ // this._rotateRight(parent);
+ // node = parent;
+ // // Update parent reference
+ // node.parent = grandparent;
+ // parent.parent = node;
+ // }
+ //
+ // // Case 3: The uncle node is black, and the current node is a right child
+ // parent.color = RBColor.BLACK;
+ // grandparent.color = RBColor.RED;
+ // this._rotateLeft(grandparent);
+ // }
+ // }
+ // }
+ //
+ // // The root node is always black
+ // this.root!.color = RBColor.BLACK;
+ // }
+ //
+ // // Left rotation operation
+ // protected _rotateLeft(node: N) {
+ // const rightChild = node.right;
+ // node.right = rightChild!.left;
+ //
+ // if (rightChild!.left) {
+ // rightChild!.left.parent = node;
+ // }
+ //
+ // rightChild!.parent = node.parent;
+ //
+ // if (node === this.root) {
+ // // @ts-ignore
+ // this._setRoot(rightChild);
+ // } else if (node === node.parent!.left) {
+ // node.parent!.left = rightChild;
+ // } else {
+ // node.parent!.right = rightChild;
+ // }
+ //
+ // rightChild!.left = node;
+ // node.parent = rightChild;
+ // }
+ //
+ // // Right rotation operation
+ // protected _rotateRight(node: N) {
+ // const leftChild = node.left;
+ // node.left = leftChild!.right;
+ //
+ // if (leftChild!.right) {
+ // leftChild!.right.parent = node;
+ // }
+ //
+ // leftChild!.parent = node.parent;
+ //
+ // if (node === this.root) {
+ // // @ts-ignore
+ // this._setRoot(leftChild);
+ // } else if (node === node.parent!.right) {
+ // node.parent!.right = leftChild;
+ // } else {
+ // node.parent!.left = leftChild;
+ // }
+ //
+ // leftChild!.right = node;
+ // node.parent = leftChild;
+ // }
+ //
+ // protected _isNodeRed(node: N | null | undefined): boolean {
+ // return node ? node.color === RBColor.RED : false;
+ // }
+ //
+ // // Find the sibling node
+ // protected _findSibling(node: N): N | null | undefined {
+ // if (!node.parent) {
+ // return undefined;
+ // }
+ //
+ // return node === node.parent.left ? node.parent.right : node.parent.left;
+ // }
+ //
+ // // Remove a node
+ // protected _removeNode(node: N, replacement: N | null | undefined): void {
+ // if (node === this.root && !replacement) {
+ // // If there's only the root node and no replacement, simply delete the root node
+ // this._setRoot(null);
+ // } else if (node === this.root || this._isNodeRed(node)) {
+ // // If the node is the root or a red node, delete it directly
+ // if (node.parent!.left === node) {
+ // node.parent!.left = replacement;
+ // } else {
+ // node.parent!.right = replacement;
+ // }
+ //
+ // if (replacement) {
+ // replacement.parent = node.parent!;
+ // replacement.color = RBColor.BLACK; // Set the replacement node's color to black
+ // }
+ // } else {
+ // // If the node is a black node, perform removal and repair
+ // const sibling = this._findSibling(node);
+ //
+ // if (node.parent!.left === node) {
+ // node.parent!.left = replacement;
+ // } else {
+ // node.parent!.right = replacement;
+ // }
+ //
+ // if (replacement) {
+ // replacement.parent = node.parent;
+ // }
+ //
+ // if (!this._isNodeRed(sibling)) {
+ // // If the sibling node is black, perform repair
+ // this._fixDeleteViolation(replacement || node);
+ // }
+ // }
+ //
+ // if (node.parent) {
+ // node.parent = null;
+ // }
+ // node.left = null;
+ // node.right = null;
+ // }
+ //
+ // override delete(keyOrNode: BTNKey | N): BinaryTreeDeletedResult[] {
+ // const node = this.get(keyOrNode);
+ // const result: BinaryTreeDeletedResult[] = [{deleted: undefined, needBalanced: null}];
+ // if (!node) return result; // Node does not exist
+ //
+ // const replacement = this._getReplacementNode(node);
+ //
+ // const isRed = this._isNodeRed(node);
+ // const isRedReplacement = this._isNodeRed(replacement);
+ //
+ // // Remove the node
+ // this._removeNode(node, replacement);
+ //
+ // if (isRed || isRedReplacement) {
+ // // If the removed node is red or the replacement node is red, no repair is needed
+ // return result;
+ // }
+ //
+ // // Repair any violation introduced by the removal
+ // this._fixDeleteViolation(replacement);
+ //
+ // return result;
+ // }
+ //
+ // // Repair operation after node deletion
+ // protected _fixDeleteViolation(node: N | null | undefined) {
+ // let sibling;
+ //
+ // while (node && node !== this.root && !this._isNodeRed(node)) {
+ // if (node === node.parent!.left) {
+ // sibling = node.parent!.right;
+ //
+ // if (sibling && this._isNodeRed(sibling)) {
+ // // Case 1: The sibling node is red
+ // sibling.color = RBColor.BLACK;
+ // node.parent!.color = RBColor.RED;
+ // this._rotateLeft(node.parent!);
+ // sibling = node.parent!.right;
+ // }
+ //
+ // if (!sibling) return;
+ //
+ // if (
+ // (!sibling.left || sibling.left.color === RBColor.BLACK) &&
+ // (!sibling.right || sibling.right.color === RBColor.BLACK)
+ // ) {
+ // // Case 2: The sibling node and its children are all black
+ // sibling.color = RBColor.RED;
+ // node = node.parent!;
+ // } else {
+ // if (!(sibling.right && this._isNodeRed(sibling.right))) {
+ // // Case 3: The sibling node is black, and the left child is red, the right child is black
+ // sibling.left!.color = RBColor.BLACK;
+ // sibling.color = RBColor.RED;
+ // this._rotateRight(sibling);
+ // sibling = node.parent!.right;
+ // }
+ //
+ // // Case 4: The sibling node is black, and the right child is red
+ // if (sibling) {
+ // sibling.color = node.parent!.color;
+ // }
+ // if (node.parent) {
+ // node.parent.color = RBColor.BLACK;
+ // }
+ // if (sibling!.right) {
+ // sibling!.right.color = RBColor.BLACK;
+ // }
+ // this._rotateLeft(node.parent!);
+ // node = this.root;
+ // }
+ // } else {
+ // // Symmetric case: The parent is the right child of the grandparent
+ // sibling = node.parent!.left;
+ //
+ // if (sibling && this._isNodeRed(sibling)) {
+ // // Case 1: The sibling node is red
+ // sibling.color = RBColor.BLACK;
+ // node.parent!.color = RBColor.RED;
+ // this._rotateRight(node.parent!);
+ // sibling = node.parent!.left;
+ // }
+ //
+ // if (!sibling) return;
+ //
+ // if (
+ // (!sibling.left || sibling.left.color === RBColor.BLACK) &&
+ // (!sibling.right || sibling.right.color === RBColor.BLACK)
+ // ) {
+ // // Case 2: The sibling node and its children are all black
+ // sibling.color = RBColor.RED;
+ // node = node.parent!;
+ // } else {
+ // if (!(sibling.left && this._isNodeRed(sibling.left))) {
+ // // Case 3: The sibling node is black, and the right child is red, the left child is black
+ // sibling.right!.color = RBColor.BLACK;
+ // sibling.color = RBColor.RED;
+ // this._rotateLeft(sibling);
+ // sibling = node.parent!.left;
+ // }
+ //
+ // // Case 4: The sibling node is black, and the left child is red
+ // if (sibling) {
+ // sibling.color = node.parent!.color;
+ // }
+ // if (node.parent) {
+ // node.parent.color = RBColor.BLACK;
+ // }
+ // if (sibling!.left) {
+ // sibling!.left.color = RBColor.BLACK;
+ // }
+ // this._rotateRight(node.parent!);
+ // node = this.root;
+ // }
+ // }
+ // }
+ //
+ // if (node) {
+ // node.color = RBColor.BLACK;
+ // }
+ // }
+ //
+ // protected _findMin(node: N): N {
+ // while (node.left) {
+ // node = node.left;
+ // }
+ // return node;
+ // }
+ //
+ // // Get the replacement node
+ // protected _getReplacementNode(node: N): N | null | undefined {
+ // if (node.left && node.right) {
+ // return this._findSuccessor(node);
+ // }
+ //
+ // if (!node.left && !node.right) {
+ // return null; // Return a fake node with color black
+ // }
+ //
+ // return node.left || node.right;
+ // }
+ //
+ // // Find the successor node
+ // protected _findSuccessor(node: N): N | null | undefined {
+ // if (node.right) {
+ // // If the node has a right child, find the minimum node in the right subtree as the successor
+ // return this._findMin(node.right);
+ // }
+ //
+ // // Otherwise, traverse upward until finding the first parent whose left child is the current node
+ // let parent = node.parent;
+ // while (parent && node === parent.right) {
+ // node = parent;
+ // parent = parent.parent;
+ // }
+ //
+ // return parent;
+ // }
+>>>>>>> 10bbcffcef4ed5901867431a3d3eae891d190b9d
}
diff --git a/src/data-structures/binary-tree/segment-tree.ts b/src/data-structures/binary-tree/segment-tree.ts
index bdb88b5..fc366e8 100644
--- a/src/data-structures/binary-tree/segment-tree.ts
+++ b/src/data-structures/binary-tree/segment-tree.ts
@@ -9,70 +9,18 @@
import type {SegmentTreeNodeVal} from '../../types';
export class SegmentTreeNode {
- constructor(start: number, end: number, sum: number, val?: SegmentTreeNodeVal | null) {
- this._start = start;
- this._end = end;
- this._sum = sum;
- this._val = val || null;
- }
+ start = 0;
+ end = 0;
+ value: SegmentTreeNodeVal | null = null;
+ sum = 0;
+ left: SegmentTreeNode | null = null;
+ right: SegmentTreeNode | null = null;
- private _start = 0;
- get start(): number {
- return this._start;
- }
-
- set start(v: number) {
- this._start = v;
- }
-
- private _end = 0;
-
- get end(): number {
- return this._end;
- }
-
- set end(v: number) {
- this._end = v;
- }
-
- private _val: SegmentTreeNodeVal | null = null;
-
- get val(): SegmentTreeNodeVal | null {
- return this._val;
- }
-
- set val(v: SegmentTreeNodeVal | null) {
- this._val = v;
- }
-
- private _sum = 0;
-
- get sum(): number {
- return this._sum;
- }
-
- set sum(v: number) {
- this._sum = v;
- }
-
- private _left: SegmentTreeNode | null = null;
-
- get left(): SegmentTreeNode | null {
- return this._left;
- }
-
- set left(v: SegmentTreeNode | null) {
- this._left = v;
- }
-
- private _right: SegmentTreeNode | null = null;
-
- get right(): SegmentTreeNode | null {
- return this._right;
- }
-
- set right(v: SegmentTreeNode | null) {
- this._right = v;
+ constructor(start: number, end: number, sum: number, value?: SegmentTreeNodeVal | null) {
+ this.start = start;
+ this.end = end;
+ this.sum = sum;
+ this.value = value || null;
}
}
@@ -101,24 +49,25 @@ export class SegmentTree {
}
}
- private _values: number[] = [];
+ protected _values: number[] = [];
get values(): number[] {
return this._values;
}
- private _start = 0;
+ protected _start = 0;
+
get start(): number {
return this._start;
}
- private _end: number;
+ protected _end: number;
get end(): number {
return this._end;
}
- private _root: SegmentTreeNode | null;
+ protected _root: SegmentTreeNode | null;
get root(): SegmentTreeNode | null {
return this._root;
@@ -154,30 +103,30 @@ export class SegmentTree {
* updated.
* @param {number} sum - The `sum` parameter represents the new value that should be assigned to the `sum` property of
* the `SegmentTreeNode` at the specified `index`.
- * @param {SegmentTreeNodeVal} [val] - The `val` parameter is an optional value that can be assigned to the `val`
+ * @param {SegmentTreeNodeVal} [value] - The `value` parameter is an optional value that can be assigned to the `value`
* property of the `SegmentTreeNode` object. It is not currently used in the code, but you can uncomment the line `//
- * cur.val = val;` and pass a value for `val` in the
+ * cur.value = value;` and pass a value for `value` in the
* @returns The function does not return anything.
*/
- updateNode(index: number, sum: number, val?: SegmentTreeNodeVal) {
+ updateNode(index: number, sum: number, value?: SegmentTreeNodeVal) {
const root = this.root || null;
if (!root) {
return;
}
- const dfs = (cur: SegmentTreeNode, index: number, sum: number, val?: SegmentTreeNodeVal) => {
+ const dfs = (cur: SegmentTreeNode, index: number, sum: number, value?: SegmentTreeNodeVal) => {
if (cur.start === cur.end && cur.start === index) {
cur.sum = sum;
- if (val !== undefined) cur.val = val;
+ if (value !== undefined) cur.value = value;
return;
}
const mid = cur.start + Math.floor((cur.end - cur.start) / 2);
if (index <= mid) {
if (cur.left) {
- dfs(cur.left, index, sum, val);
+ dfs(cur.left, index, sum, value);
}
} else {
if (cur.right) {
- dfs(cur.right, index, sum, val);
+ dfs(cur.right, index, sum, value);
}
}
if (cur.left && cur.right) {
@@ -185,7 +134,7 @@ export class SegmentTree {
}
};
- dfs(root, index, sum, val);
+ dfs(root, index, sum, value);
}
/**
@@ -238,20 +187,4 @@ export class SegmentTree {
};
return dfs(root, indexA, indexB);
}
-
- protected _setValues(value: number[]) {
- this._values = value;
- }
-
- protected _setStart(value: number) {
- this._start = value;
- }
-
- protected _setEnd(value: number) {
- this._end = value;
- }
-
- protected _setRoot(v: SegmentTreeNode | null) {
- this._root = v;
- }
}
diff --git a/src/data-structures/binary-tree/tree-multiset.ts b/src/data-structures/binary-tree/tree-multiset.ts
index f048cbf..7bea74a 100644
--- a/src/data-structures/binary-tree/tree-multiset.ts
+++ b/src/data-structures/binary-tree/tree-multiset.ts
@@ -5,40 +5,39 @@
* @copyright Copyright (c) 2022 Tyler Zeng
* @license MIT License
*/
-import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
-import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType} from '../../types';
+import type {BTNKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
+import {BinaryTreeDeletedResult, BTNCallback, CP, FamilyPosition, IterationType} from '../../types';
import {IBinaryTree} from '../../interfaces';
import {AVLTree, AVLTreeNode} from './avl-tree';
export class TreeMultisetNode<
V = any,
- FAMILY extends TreeMultisetNode = TreeMultisetNodeNested
-> extends AVLTreeNode {
+ N extends TreeMultisetNode = TreeMultisetNodeNested
+> extends AVLTreeNode {
+ count: number;
+
/**
* The constructor function initializes a BinaryTreeNode object with a key, value, and count.
- * @param {BinaryTreeNodeKey} key - The `key` parameter is of type `BinaryTreeNodeKey` and represents the unique identifier
+ * @param {BTNKey} key - The `key` parameter is of type `BTNKey` and represents the unique identifier
* of the binary tree node.
- * @param {V} [val] - The `val` parameter is an optional parameter of type `V`. It represents the value of the binary
+ * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary
* tree node. If no value is provided, it will be `undefined`.
* @param {number} [count=1] - The `count` parameter is a number that represents the number of times a particular value
* occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
* parameter when creating a new instance of the `BinaryTreeNode` class.
*/
- constructor(key: BinaryTreeNodeKey, val?: V, count = 1) {
- super(key, val);
+ constructor(key: BTNKey, value?: V, count = 1) {
+ super(key, value);
this.count = count;
}
-
- count: number;
}
/**
* The only distinction between a TreeMultiset and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
*/
-export class TreeMultiset = TreeMultisetNode>
- extends AVLTree
- implements IBinaryTree
-{
+export class TreeMultiset = TreeMultisetNode>>
+ extends AVLTree
+ implements IBinaryTree {
/**
* The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to
* merge duplicated values.
@@ -57,67 +56,43 @@ export class TreeMultiset = TreeMultiset
/**
* The function creates a new BSTNode with the given key, value, and count.
- * @param {BinaryTreeNodeKey} key - The key parameter is the unique identifier for the binary tree node. It is used to
+ * @param {BTNKey} key - The key parameter is the unique identifier for the binary tree node. It is used to
* distinguish one node from another in the tree.
- * @param {N} val - The `val` parameter represents the value that will be stored in the binary search tree node.
+ * @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.
* @param {number} [count] - The "count" parameter is an optional parameter of type number. It represents the number of
* occurrences of the value in the binary search tree node. If not provided, the count will default to 1.
* @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).
*/
- override createNode(key: BinaryTreeNodeKey, val?: N['val'], count?: number): N {
- return new TreeMultisetNode(key, val, count) as N;
+ override createNode(key: BTNKey, value?: V, count?: number): N {
+ return new TreeMultisetNode(key, value, count) as N;
}
/**
- * The function swaps the location of two nodes in a tree data structure.
- * @param {N} srcNode - The source node that we want to swap with the destination node.
- * @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
- * be swapped with.
- * @returns the `destNode` after swapping its values with the `srcNode`.
+ * The `add` function adds a new node to a binary search tree, updating the count if the key already
+ * exists, and balancing the tree if necessary.
+ * @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
+ * `BTNKey` (which represents the key of the node to be added), a `N` (which represents a
+ * node to be added), or `null` (which represents a null node).
+ * @param [value] - The `value` parameter represents the value associated with the key that is being
+ * added to the binary tree.
+ * @param [count=1] - The `count` parameter represents the number of occurrences of the key/value
+ * pair that will be added to the binary tree. It has a default value of 1, which means that if no
+ * count is specified, the default count will be 1.
+ * @returns The function `add` returns a value of type `N | null | undefined`.
*/
- override swapLocation(srcNode: N, destNode: N): N {
- const {key, val, count, height} = destNode;
- const tempNode = this.createNode(key, val, count);
- if (tempNode) {
- tempNode.height = height;
-
- destNode.key = srcNode.key;
- destNode.val = srcNode.val;
- destNode.count = srcNode.count;
- destNode.height = srcNode.height;
-
- srcNode.key = tempNode.key;
- srcNode.val = tempNode.val;
- srcNode.count = tempNode.count;
- srcNode.height = tempNode.height;
- }
-
- return destNode;
- }
-
- /**
- * The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if
- * necessary.
- * @param {BinaryTreeNodeKey | N} keyOrNode - The `keyOrNode` parameter can be either a `BinaryTreeNodeKey` or a `N` (which
- * represents a `BinaryTreeNode`).
- * @param [val] - The `val` parameter represents the value to be added to the binary tree node.
- * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the
- * value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
- * @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`.
- */
- override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val'], count = 1): N | null | undefined {
+ override add(keyOrNode: BTNKey | N | null, value?: V, count = 1): N | null | undefined {
let inserted: N | null | undefined = undefined,
newNode: N | null;
if (keyOrNode instanceof TreeMultisetNode) {
- newNode = this.createNode(keyOrNode.key, keyOrNode.val, keyOrNode.count);
+ newNode = this.createNode(keyOrNode.key, keyOrNode.value, keyOrNode.count);
} else if (keyOrNode === null) {
newNode = null;
} else {
- newNode = this.createNode(keyOrNode, val, count);
+ newNode = this.createNode(keyOrNode, value, count);
}
if (!this.root) {
this._setRoot(newNode);
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
newNode && this._setCount(this.count + newNode.count);
inserted = this.root;
} else {
@@ -127,7 +102,7 @@ export class TreeMultiset = TreeMultiset
if (cur) {
if (newNode) {
if (this._compare(cur.key, newNode.key) === CP.eq) {
- cur.val = newNode.val;
+ cur.value = newNode.value;
cur.count += newNode.count;
this._setCount(this.count + newNode.count);
traversing = false;
@@ -137,7 +112,7 @@ export class TreeMultiset = TreeMultiset
if (cur.left === undefined) {
//Add to the left of the current node
cur.left = newNode;
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
this._setCount(this.count + newNode.count);
traversing = false;
@@ -151,7 +126,7 @@ export class TreeMultiset = TreeMultiset
if (cur.right === undefined) {
//Add to the right of the current node
cur.right = newNode;
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
this._setCount(this.count + newNode.count);
traversing = false;
@@ -174,20 +149,19 @@ export class TreeMultiset = TreeMultiset
}
/**
- * The function adds a new node to a binary tree if there is an available slot on the left or right side of the parent
- * node.
- * @param {N | null} newNode - The `newNode` parameter represents the node that needs to be added to the tree. It can
- * be either a node object (`N`) or `null`.
- * @param {N} parent - The `parent` parameter represents the parent node to which the new node will be added as a
- * child.
- * @returns The method returns either the `parent.left`, `parent.right`, or `undefined`.
+ * The function adds a new node to a binary tree if there is an available slot in the parent node.
+ * @param {N | null} newNode - The `newNode` parameter represents the node that needs to be added to
+ * the tree. It can be either a node object (`N`) or `null`.
+ * @param {N} parent - The `parent` parameter represents the parent node to which the new node will
+ * be added as a child.
+ * @returns The method `_addTo` returns either the `parent.left`, `parent.right`, or `undefined`.
*/
override _addTo(newNode: N | null, parent: N): N | null | undefined {
if (parent) {
if (parent.left === undefined) {
parent.left = newNode;
if (newNode !== null) {
- this._setSize(this.size + 1);
+ this._size = this.size + 1;
this._setCount(this.count + newNode.count);
}
@@ -195,7 +169,7 @@ export class TreeMultiset = TreeMultiset
} else if (parent.right === undefined) {
parent.right = newNode;
if (newNode !== null) {
- this._setSize(this.size + 1);
+ this._size = (this.size + 1);
this._setCount(this.count + newNode.count);
}
return parent.right;
@@ -208,31 +182,28 @@ export class TreeMultiset = TreeMultiset
}
/**
- * The `addMany` function takes an array of node IDs or nodes and adds them to the tree multiset, returning an array of
- * the inserted nodes.
- * @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of BinaryTreeNodeKey or BinaryTreeNode
- * objects, or null values.
- * @param {N['val'][]} [data] - The `data` parameter is an optional array of values (`N['val'][]`) that corresponds to
- * the nodes being added. It is used when adding nodes using the `keyOrNode` and `data` arguments in the `this.add()`
- * method. If provided, the `data` array should
+ * The `addMany` function adds multiple keys or nodes to a TreeMultiset and returns an array of the
+ * inserted nodes.
+ * @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of keys or nodes to be
+ * added to the multiset. Each element can be either a BTNKey or a TreeMultisetNode.
+ * @param {V[]} [data] - The `data` parameter is an optional array of values that correspond
+ * to the keys or nodes being added to the multiset. It is used to associate additional data with
+ * each key or node.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
- override addMany(
- keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
- data?: N['val'][]
- ): (N | null | undefined)[] {
+ override addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: V[]): (N | null | undefined)[] {
const inserted: (N | null | undefined)[] = [];
for (let i = 0; i < keysOrNodes.length; i++) {
const keyOrNode = keysOrNodes[i];
if (keyOrNode instanceof TreeMultisetNode) {
- inserted.push(this.add(keyOrNode.key, keyOrNode.val, keyOrNode.count));
+ inserted.push(this.add(keyOrNode.key, keyOrNode.value, keyOrNode.count));
continue;
}
if (keyOrNode === null) {
- inserted.push(this.add(NaN, null, 0));
+ inserted.push(this.add(NaN, undefined, 0));
continue;
}
@@ -242,23 +213,26 @@ export class TreeMultiset = TreeMultiset
}
/**
- * The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
- * constructs a balanced binary search tree using either a recursive or iterative approach.
- * @returns The function `perfectlyBalance()` returns a boolean value.
+ * The `perfectlyBalance` function in TypeScript takes a sorted array of nodes and builds a balanced
+ * binary search tree using either a recursive or iterative approach.
+ * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
+ * type of iteration to use when building a balanced binary search tree. It can have two possible
+ * values:
+ * @returns a boolean value.
*/
- override perfectlyBalance(): boolean {
- const sorted = this.dfs('in', 'node'),
+ override perfectlyBalance(iterationType = this.iterationType): boolean {
+ const sorted = this.dfs(node => node, 'in'),
n = sorted.length;
if (sorted.length < 1) return false;
this.clear();
- if (this.loopType === LoopType.RECURSIVE) {
+ if (iterationType === IterationType.RECURSIVE) {
const buildBalanceBST = (l: number, r: number) => {
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
- this.add(midNode.key, midNode.val, midNode.count);
+ this.add(midNode.key, midNode.value, midNode.count);
buildBalanceBST(l, m - 1);
buildBalanceBST(m + 1, r);
};
@@ -274,7 +248,7 @@ export class TreeMultiset = TreeMultiset
if (l <= r) {
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
- this.add(midNode.key, midNode.val, midNode.count);
+ this.add(midNode.key, midNode.value, midNode.count);
stack.push([m + 1, r]);
stack.push([l, m - 1]);
}
@@ -285,19 +259,30 @@ export class TreeMultiset = TreeMultiset
}
/**
- * The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
- * node that needs to be balanced.
- * @param {N | BinaryTreeNodeKey | null} nodeOrKey - The `nodeOrKey` parameter can be one of the following:
- * @param {boolean} [ignoreCount] - The `ignoreCount` parameter is an optional boolean parameter that determines
- * whether to ignore the count of the node being removed. If `ignoreCount` is set to `true`, the count of the node will
- * not be taken into account when removing it. If `ignoreCount` is set to `false
- * @returns The function `remove` returns an array of `BinaryTreeDeletedResult` objects.
+ * The `delete` function in a binary search tree deletes a node from the tree and returns the deleted
+ * node along with the parent node that needs to be balanced.
+ * @param {ReturnType} identifier - The `identifier` parameter is either a
+ * `BTNKey` or a generic type `N`. It represents the property of the node that we are
+ * searching for. It can be a specific key value or any other property of the node.
+ * @param callback - The `callback` parameter is a function that takes a node as input and returns a
+ * value. This value is compared with the `identifier` parameter to determine if the node should be
+ * included in the result. The `callback` parameter has a default value of
+ * `((node: N) => node.key)`
+ * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node
+ * being deleted. If set to true, the count of the node will not be considered and the node will be
+ * deleted regardless of its count. If set to false (default), the count of the node will be
+ * decremented by 1 and
+ * @returns The method `delete` returns an array of `BinaryTreeDeletedResult` objects.
*/
- override remove(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult[] {
+ override delete>(
+ identifier: ReturnType,
+ callback: C = ((node: N) => node.key) as C,
+ ignoreCount = false
+ ): BinaryTreeDeletedResult[] {
const bstDeletedResult: BinaryTreeDeletedResult[] = [];
if (!this.root) return bstDeletedResult;
- const curr: N | null = this.get(nodeOrKey);
+ const curr: N | null = this.get(identifier, callback);
if (!curr) return bstDeletedResult;
const parent: N | null = curr?.parent ? curr.parent : null;
@@ -324,7 +309,7 @@ export class TreeMultiset = TreeMultiset
const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
if (leftSubTreeRightMost) {
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
- orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
+ orgCurrent = this._swap(curr, leftSubTreeRightMost);
if (parentOfLeftSubTreeMax) {
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
@@ -335,7 +320,7 @@ export class TreeMultiset = TreeMultiset
}
}
}
- this._setSize(this.size - 1);
+ this._size = this.size - 1;
// TODO How to handle when the count of target node is lesser than current node's count
this._setCount(this.count - orgCurrent.count);
}
@@ -350,328 +335,7 @@ export class TreeMultiset = TreeMultiset
}
/**
- * The function `getSubTreeCount` calculates the number of nodes and the sum of their counts in a subtree, using either
- * recursive or iterative traversal.
- * @param {N | null | undefined} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree in a
- * binary tree.
- * @returns The function `getSubTreeCount` returns an array `[number, number]`.
- */
- getSubTreeCount(subTreeRoot: N | null | undefined) {
- const res: [number, number] = [0, 0];
- if (!subTreeRoot) return res;
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N) => {
- res[0]++;
- res[1] += cur.count;
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
- };
-
- _traverse(subTreeRoot);
- return res;
- } else {
- const stack: N[] = [subTreeRoot];
-
- while (stack.length > 0) {
- const cur = stack.pop()!;
- res[0]++;
- res[1] += cur.count;
- cur.right && stack.push(cur.right);
- cur.left && stack.push(cur.left);
- }
-
- return res;
- }
- }
-
- /**
- * The function `subTreeSumCount` calculates the sum of the `count` property of each node in a subtree, either
- * recursively or iteratively.
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree
- * in a binary tree. It can be either a `BinaryTreeNodeKey` (a unique identifier for a node in the binary tree) or
- * `null` if the subtree is empty.
- * @returns the sum of the count values of all nodes in the subtree rooted at `subTreeRoot`.
- */
- subTreeSumCount(subTreeRoot: N | BinaryTreeNodeKey | null): number {
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
-
- if (!subTreeRoot) return 0;
-
- let sum = 0;
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N): void => {
- sum += cur.count;
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
- };
-
- _traverse(subTreeRoot);
- } else {
- const stack: N[] = [subTreeRoot];
-
- while (stack.length > 0) {
- const cur = stack.pop()!;
- sum += cur.count;
- cur.right && stack.push(cur.right);
- cur.left && stack.push(cur.left);
- }
- }
-
- return sum;
- }
-
- /**
- * The function `subTreeAddCount` recursively or iteratively traverses a binary tree and adds a given delta value to
- * the `count` property of each node.
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree
- * in a binary tree. It can be either a `BinaryTreeNodeKey` (a unique identifier for a node in the binary tree), a
- * `BinaryTreeNode` object, or `null` if the subtree is empty.
- * @param {number} delta - The delta parameter is a number that represents the amount by which the count of each node
- * in the subtree should be increased or decreased.
- * @returns a boolean value.
- */
- subTreeAddCount(subTreeRoot: N | BinaryTreeNodeKey | null, delta: number): boolean {
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
-
- if (!subTreeRoot) return false;
-
- const _addByProperty = (cur: N) => {
- cur.count += delta;
- this._setCount(this.count + delta);
- };
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N) => {
- _addByProperty(cur);
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
- };
-
- _traverse(subTreeRoot);
- } else {
- const stack: N[] = [subTreeRoot];
-
- while (stack.length > 0) {
- const cur = stack.pop()!;
-
- _addByProperty(cur);
- cur.right && stack.push(cur.right);
- cur.left && stack.push(cur.left);
- }
- }
- return true;
- }
-
- /**
- * The function `getNodesByCount` returns an array of nodes that have a specific count property, either recursively or
- * using a queue.
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or a
- * `N`. It represents the property of the nodes that you want to search for.
- * @param {boolean} [onlyOne] - The `onlyOne` parameter is an optional boolean parameter that determines whether to
- * return only one node that matches the `nodeProperty` or all nodes that match the `nodeProperty`. If `onlyOne` is set
- * to `true`, the function will return only one node. If `onlyOne`
- * @returns an array of nodes that match the given nodeProperty.
- */
- getNodesByCount(nodeProperty: BinaryTreeNodeKey | N, onlyOne = false): N[] {
- if (!this.root) return [];
- const result: N[] = [];
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N) => {
- if (cur.count === nodeProperty) {
- result.push(cur);
- if (onlyOne) return;
- }
-
- if (!cur.left && !cur.right) return;
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
- };
-
- _traverse(this.root);
- } else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
- const cur = queue.shift();
- if (cur) {
- if (cur.count === nodeProperty) {
- result.push(cur);
- if (onlyOne) return result;
- }
-
- cur.left && queue.push(cur.left);
- cur.right && queue.push(cur.right);
- }
- }
- }
-
- return result;
- }
-
- /**
- * The BFSCount function returns an array of counts from a breadth-first search of nodes.
- * @returns The BFSCount() function returns an array of numbers, specifically the count property of each node in the
- * bfs traversal.
- */
- BFSCount(): number[] {
- const nodes = super.bfs('node');
- return nodes.map(node => node.count);
- }
-
- /**
- * The function "listLevelsCount" takes a node and returns an array of arrays, where each inner array contains the
- * count property of each node at that level.
- * @param {N | null} node - The parameter `node` is of type `N | null`. This means that it can either be an instance of
- * the class `N` or `null`.
- * @returns a 2D array of numbers. Each inner array represents a level in the binary tree, and each number in the inner
- * array represents the count property of a node in that level.
- */
- listLevelsCount(node: N | null): number[][] {
- const levels = super.listLevels(node, 'node');
- return levels.map(level => level.map(node => node.count));
- }
-
- /**
- * The `morrisCount` function returns an array of counts for each node in a binary tree, based on a specified traversal
- * pattern.
- * @param {'in' | 'pre' | 'post'} [pattern] - The `pattern` parameter is an optional parameter that specifies the
- * traversal pattern for the Morris traversal algorithm. It can have one of three values: 'in', 'pre', or 'post'.
- * @returns The function `morrisCount` returns an array of numbers.
- */
- morrisCount(pattern: DFSOrderPattern = 'in'): number[] {
- const nodes = super.morris(pattern, 'node');
- return nodes.map(node => node.count);
- }
-
- /**
- * The function dfsCountIterative performs an iterative depth-first search and returns an array of node counts based on
- * the specified traversal pattern.
- * @param {'in' | 'pre' | 'post'} [pattern] - The pattern parameter is a string that specifies the traversal order for
- * the Depth-First Search (dfs) algorithm. It can have three possible values: 'in', 'pre', or 'post'.
- * @returns The dfsCountIterative function returns an array of numbers, which represents the count property of each node
- * in the dfs traversal.
- */
- dfsCountIterative(pattern: DFSOrderPattern = 'in'): number[] {
- const nodes = super.dfsIterative(pattern, 'node');
- return nodes.map(node => node.count);
- }
-
- /**
- * The dfsCount function returns an array of counts for each node in a depth-first search traversal.
- * @param {DFSOrderPattern} [pattern] - The pattern parameter is an optional parameter that specifies the order in which
- * the Depth-First Search (dfs) algorithm should traverse the nodes. It can have one of the following values:
- * @returns The dfsCount function returns an array of numbers, specifically the count property of each node in the dfs
- * traversal.
- */
- dfsCount(pattern: DFSOrderPattern = 'in'): number[] {
- const nodes = super.dfs(pattern, 'node');
- return nodes.map(node => node.count);
- }
-
- /**
- * The `lesserSumCount` function calculates the sum of the counts of all nodes in a binary tree that have a lesser
- * value than a given node.
- * @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
- * @returns the sum of the counts of nodes in the binary tree that have a lesser value than the given beginNode.
- */
- lesserSumCount(beginNode: N | BinaryTreeNodeKey | null): number {
- if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'key');
- if (!beginNode) return 0;
- if (!this.root) return 0;
- const key = beginNode.key;
-
- let sum = 0;
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N): void => {
- const compared = this._compare(cur.key, key);
- if (compared === CP.eq) {
- if (cur.right) sum += this.subTreeSumCount(cur.right);
- return;
- } else if (compared === CP.lt) {
- if (cur.left) sum += this.subTreeSumCount(cur.left);
- sum += cur.count;
- if (cur.right) _traverse(cur.right);
- else return;
- } else {
- if (cur.left) _traverse(cur.left);
- else return;
- }
- };
-
- _traverse(this.root);
- } else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
- const cur = queue.shift();
- if (cur) {
- const compared = this._compare(cur.key, key);
- if (compared === CP.eq) {
- if (cur.right) sum += this.subTreeSumCount(cur.right);
- return sum;
- } else if (compared === CP.lt) {
- // todo maybe a bug
- if (cur.left) sum += this.subTreeSumCount(cur.left);
- sum += cur.count;
- if (cur.right) queue.push(cur.right);
- else return sum;
- } else {
- if (cur.left) queue.push(cur.left);
- else return sum;
- }
- }
- }
- }
-
- return sum;
- }
-
- /**
- * The function `allGreaterNodesAddCount` updates the count property of all nodes in a binary tree that have an ID
- * greater than a given ID by a specified delta value.
- * @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be one of the following:
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the `count` property
- * of each node should be increased.
- * @returns a boolean value.
- */
- allGreaterNodesAddCount(node: N | BinaryTreeNodeKey | null, delta: number): boolean {
- if (typeof node === 'number') node = this.get(node, 'key');
- if (!node) return false;
- const key = node.key;
- if (!this.root) return false;
-
- if (this.loopType === LoopType.RECURSIVE) {
- const _traverse = (cur: N) => {
- const compared = this._compare(cur.key, key);
- if (compared === CP.gt) cur.count += delta;
-
- if (!cur.left && !cur.right) return;
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) _traverse(cur.left);
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) _traverse(cur.right);
- };
-
- _traverse(this.root);
- return true;
- } else {
- const queue: N[] = [this.root];
- while (queue.length > 0) {
- const cur = queue.shift();
- if (cur) {
- const compared = this._compare(cur.key, key);
- if (compared === CP.gt) cur.count += delta;
-
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) queue.push(cur.left);
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) queue.push(cur.right);
- }
- }
- return true;
- }
- }
-
- /**
- * The clear() function clears the data and sets the count to 0.
+ * The clear() function clears the contents of a data structure and sets the count to zero.
*/
clear() {
super.clear();
@@ -679,7 +343,34 @@ export class TreeMultiset = TreeMultiset
}
/**
- * The function "_setCount" is used to set the value of the "_count" property.
+ * The function swaps the values of two nodes in a binary tree.
+ * @param {N} srcNode - The source node that needs to be swapped with the destination node.
+ * @param {N} destNode - The `destNode` parameter represents the destination node where the values
+ * from `srcNode` will be swapped into.
+ * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.
+ */
+ protected override _swap(srcNode: N, destNode: N): N {
+ const {key, value, count, height} = destNode;
+ const tempNode = this.createNode(key, value, count);
+ if (tempNode) {
+ tempNode.height = height;
+
+ destNode.key = srcNode.key;
+ destNode.value = srcNode.value;
+ destNode.count = srcNode.count;
+ destNode.height = srcNode.height;
+
+ srcNode.key = tempNode.key;
+ srcNode.value = tempNode.value;
+ srcNode.count = tempNode.count;
+ srcNode.height = tempNode.height;
+ }
+
+ return destNode;
+ }
+
+ /**
+ * The function sets the value of the "_count" property.
* @param {number} v - number
*/
protected _setCount(v: number) {
diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts
index 92b5380..6cd5504 100644
--- a/src/data-structures/graph/abstract-graph.ts
+++ b/src/data-structures/graph/abstract-graph.ts
@@ -9,77 +9,45 @@ import {arrayRemove, uuidV4} from '../../utils';
import {PriorityQueue} from '../priority-queue';
import type {DijkstraResult, VertexKey} from '../../types';
import {IGraph} from '../../interfaces';
+import {Queue} from '../queue';
export abstract class AbstractVertex {
+ key: VertexKey;
+ value: V | undefined;
+
/**
* The function is a protected constructor that takes an key and an optional value as parameters.
* @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is
* used to uniquely identify the vertex object.
- * @param {V} [val] - The parameter "val" is an optional parameter of type V. It is used to assign a value to the
+ * @param {V} [value] - The parameter "value" is an optional parameter of type V. It is used to assign a value to the
* vertex. If no value is provided, it will be set to undefined.
*/
- protected constructor(key: VertexKey, val?: V) {
- this._key = key;
- this._val = val;
+ protected constructor(key: VertexKey, value?: V) {
+ this.key = key;
+ this.value = value;
}
- private _key: VertexKey;
-
- get key(): VertexKey {
- return this._key;
- }
-
- set key(v: VertexKey) {
- this._key = v;
- }
-
- private _val: V | undefined;
-
- get val(): V | undefined {
- return this._val;
- }
-
- set val(value: V | undefined) {
- this._val = value;
- }
}
-export abstract class AbstractEdge