diff --git a/README.md b/README.md index a28ff33..b3d976f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ anymore! JavaScript and TypeScript now have [data-structure-typed]().**`Benchmar ### We provide data structures that are not available in JS/TS -Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, Directed Graph, Undirected Graph, BST, AVL Tree, Priority Queue, Queue, Tree Multiset, Linked List. +Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, Directed Graph, Undirected Graph, BST, AVL Tree, Priority Queue, Queue, Tree Multiset. ### Performance surpasses that of native JS/TS @@ -1033,5 +1033,3 @@ avl2.print(); [//]: # (No deletion!!! End of Replace Section) - - diff --git a/README_zh-CN.md b/README_zh-CN.md index 7d72ecb..03e2232 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -25,7 +25,7 @@ JavaScript和TypeScript的数据结构。 ### 提供了JS/TS中没有的数据结构 -Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, Directed Graph, Undirected Graph, BST, AVL Tree, Priority Queue, Queue, Tree Multiset, Linked List. +Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, Directed Graph, Undirected Graph, BST, AVL Tree, Priority Queue, Queue, Tree Multiset. ### 性能超越原生JS/TS diff --git a/package-lock.json b/package-lock.json index cb35fa9..774c0b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-structure-typed", - "version": "1.48.3", + "version": "1.49.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.48.3", + "version": "1.49.4", "license": "MIT", "devDependencies": { "@swc/core": "^1.3.96", @@ -38,7 +38,7 @@ "ts-loader": "^9.4.4", "ts-node": "^10.9.1", "tsup": "^7.2.0", - "typedoc": "^0.25.1", + "typedoc": "^0.25.4", "typescript": "^5.3.2" } }, @@ -143,21 +143,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -182,12 +182,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.23.5", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -197,14 +197,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -347,14 +347,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" @@ -431,9 +431,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -634,20 +634,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/generator": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -664,9 +664,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1127,9 +1127,9 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1168,6 +1168,50 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1893,6 +1937,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1918,9 +1972,9 @@ } }, "node_modules/@swc/core": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.100.tgz", - "integrity": "sha512-7dKgTyxJjlrMwFZYb1auj3Xq0D8ZBe+5oeIgfMlRU05doXZypYJe0LAk0yjj3WdbwYzpF+T1PLxwTWizI0pckw==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.101.tgz", + "integrity": "sha512-w5aQ9qYsd/IYmXADAnkXPGDMTqkQalIi+kfFf/MHRKTpaOL7DHjMXwPp/n8hJ0qNjRvchzmPtOqtPBiER50d8A==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1935,15 +1989,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.100", - "@swc/core-darwin-x64": "1.3.100", - "@swc/core-linux-arm64-gnu": "1.3.100", - "@swc/core-linux-arm64-musl": "1.3.100", - "@swc/core-linux-x64-gnu": "1.3.100", - "@swc/core-linux-x64-musl": "1.3.100", - "@swc/core-win32-arm64-msvc": "1.3.100", - "@swc/core-win32-ia32-msvc": "1.3.100", - "@swc/core-win32-x64-msvc": "1.3.100" + "@swc/core-darwin-arm64": "1.3.101", + "@swc/core-darwin-x64": "1.3.101", + "@swc/core-linux-arm-gnueabihf": "1.3.101", + "@swc/core-linux-arm64-gnu": "1.3.101", + "@swc/core-linux-arm64-musl": "1.3.101", + "@swc/core-linux-x64-gnu": "1.3.101", + "@swc/core-linux-x64-musl": "1.3.101", + "@swc/core-win32-arm64-msvc": "1.3.101", + "@swc/core-win32-ia32-msvc": "1.3.101", + "@swc/core-win32-x64-msvc": "1.3.101" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -1955,9 +2010,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.100.tgz", - "integrity": "sha512-XVWFsKe6ei+SsDbwmsuRkYck1SXRpO60Hioa4hoLwR8fxbA9eVp6enZtMxzVVMBi8ej5seZ4HZQeAWepbukiBw==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.101.tgz", + "integrity": "sha512-mNFK+uHNPRXSnfTOG34zJOeMl2waM4hF4a2NY7dkMXrPqw9CoJn4MwTXJcyMiSz1/BnNjjTCHF3Yhj0jPxmkzQ==", "cpu": [ "arm64" ], @@ -1971,9 +2026,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.100.tgz", - "integrity": "sha512-KF/MXrnH1nakm1wbt4XV8FS7kvqD9TGmVxeJ0U4bbvxXMvzeYUurzg3AJUTXYmXDhH/VXOYJE5N5RkwZZPs5iA==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.101.tgz", + "integrity": "sha512-B085j8XOx73Fg15KsHvzYWG262bRweGr3JooO1aW5ec5pYbz5Ew9VS5JKYS03w2UBSxf2maWdbPz2UFAxg0whw==", "cpu": [ "x64" ], @@ -1986,10 +2041,26 @@ "node": ">=10" } }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.101.tgz", + "integrity": "sha512-9xLKRb6zSzRGPqdz52Hy5GuB1lSjmLqa0lST6MTFads3apmx4Vgs8Y5NuGhx/h2I8QM4jXdLbpqQlifpzTlSSw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.100.tgz", - "integrity": "sha512-p8hikNnAEJrw5vHCtKiFT4hdlQxk1V7vqPmvUDgL/qe2menQDK/i12tbz7/3BEQ4UqUPnvwpmVn2d19RdEMNxw==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.101.tgz", + "integrity": "sha512-oE+r1lo7g/vs96Weh2R5l971dt+ZLuhaUX+n3BfDdPxNHfObXgKMjO7E+QS5RbGjv/AwiPCxQmbdCp/xN5ICJA==", "cpu": [ "arm64" ], @@ -2003,9 +2074,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.100.tgz", - "integrity": "sha512-BWx/0EeY89WC4q3AaIaBSGfQxkYxIlS3mX19dwy2FWJs/O+fMvF9oLk/CyJPOZzbp+1DjGeeoGFuDYpiNO91JA==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.101.tgz", + "integrity": "sha512-OGjYG3H4BMOTnJWJyBIovCez6KiHF30zMIu4+lGJTCrxRI2fAjGLml3PEXj8tC3FMcud7U2WUn6TdG0/te2k6g==", "cpu": [ "arm64" ], @@ -2019,9 +2090,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.100.tgz", - "integrity": "sha512-XUdGu3dxAkjsahLYnm8WijPfKebo+jHgHphDxaW0ovI6sTdmEGFDew7QzKZRlbYL2jRkUuuKuDGvD6lO5frmhA==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.101.tgz", + "integrity": "sha512-/kBMcoF12PRO/lwa8Z7w4YyiKDcXQEiLvM+S3G9EvkoKYGgkkz4Q6PSNhF5rwg/E3+Hq5/9D2R+6nrkF287ihg==", "cpu": [ "x64" ], @@ -2035,9 +2106,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.100.tgz", - "integrity": "sha512-PhoXKf+f0OaNW/GCuXjJ0/KfK9EJX7z2gko+7nVnEA0p3aaPtbP6cq1Ubbl6CMoPL+Ci3gZ7nYumDqXNc3CtLQ==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.101.tgz", + "integrity": "sha512-kDN8lm4Eew0u1p+h1l3JzoeGgZPQ05qDE0czngnjmfpsH2sOZxVj1hdiCwS5lArpy7ktaLu5JdRnx70MkUzhXw==", "cpu": [ "x64" ], @@ -2051,9 +2122,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.100.tgz", - "integrity": "sha512-PwLADZN6F9cXn4Jw52FeP/MCLVHm8vwouZZSOoOScDtihjY495SSjdPnlosMaRSR4wJQssGwiD/4MbpgQPqbAw==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.101.tgz", + "integrity": "sha512-9Wn8TTLWwJKw63K/S+jjrZb9yoJfJwCE2RV5vPCCWmlMf3U1AXj5XuWOLUX+Rp2sGKau7wZKsvywhheWm+qndQ==", "cpu": [ "arm64" ], @@ -2067,9 +2138,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.100.tgz", - "integrity": "sha512-0f6nicKSLlDKlyPRl2JEmkpBV4aeDfRQg6n8mPqgL7bliZIcDahG0ej+HxgNjZfS3e0yjDxsNRa6sAqWU2Z60A==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.101.tgz", + "integrity": "sha512-onO5KvICRVlu2xmr4//V2je9O2XgS1SGKpbX206KmmjcJhXN5EYLSxW9qgg+kgV5mip+sKTHTAu7IkzkAtElYA==", "cpu": [ "ia32" ], @@ -2083,9 +2154,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.100", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.100.tgz", - "integrity": "sha512-b7J0rPoMkRTa3XyUGt8PwCaIBuYWsL2DqbirrQKRESzgCvif5iNpqaM6kjIjI/5y5q1Ycv564CB51YDpiS8EtQ==", + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.101.tgz", + "integrity": "sha512-T3GeJtNQV00YmiVw/88/nxJ/H43CJvFnpvBHCVn17xbahiVUOPOduh3rc9LgAkKiNt/aV8vU3OJR+6PhfMR7UQ==", "cpu": [ "x64" ], @@ -2171,9 +2242,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", - "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -2205,9 +2276,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.44.8", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", - "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-FlsN0p4FhuYRjIxpbdXovvHQhtlG05O1GG/RNWvdAxTboR438IOTwmrY/vLA+Xfgg06BTkP045M3vpFwTMv1dg==", "dev": true, "peer": true, "dependencies": { @@ -2298,9 +2369,9 @@ } }, "node_modules/@types/node": { - "version": "20.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", - "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -2340,16 +2411,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz", - "integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.15.0.tgz", + "integrity": "sha512-j5qoikQqPccq9QoBAupOP+CBu8BaJ8BLjaXSioDISeTZkVO3ig7oSIKh3H+rEpee7xCXtWwSB4KIL5l6hWZzpg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/type-utils": "6.13.2", - "@typescript-eslint/utils": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/type-utils": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2375,15 +2446,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz", - "integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.15.0.tgz", + "integrity": "sha512-MkgKNnsjC6QwcMdlNAel24jjkEO/0hQaMDLqP4S9zq5HBAUJNQB6y+3DwLjX7b3l2b37eNAxMPLwb3/kh8VKdA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4" }, "engines": { @@ -2403,13 +2474,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.15.0.tgz", + "integrity": "sha512-+BdvxYBltqrmgCNu4Li+fGDIkW9n//NrruzG9X1vBzaNK+ExVXPoGB71kneaVw/Jp+4rH/vaMAGC6JfMbHstVg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2420,13 +2491,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz", - "integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.15.0.tgz", + "integrity": "sha512-CnmHKTfX6450Bo49hPg2OkIm/D/TVYV7jO1MCfPYGwf6x3GO0VU8YMO5AYMn+u3X05lRRxA4fWCz87GFQV6yVQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.13.2", - "@typescript-eslint/utils": "6.13.2", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/utils": "6.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2447,9 +2518,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.15.0.tgz", + "integrity": "sha512-yXjbt//E4T/ee8Ia1b5mGlbNj9fB9lJP4jqLbZualwpP2BCQ5is6BcWwxpIsY4XKAhmdv3hrW92GdtJbatC6dQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2460,13 +2531,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.15.0.tgz", + "integrity": "sha512-7mVZJN7Hd15OmGuWrp2T9UvqR2Ecg+1j/Bp1jXUEY2GZKV6FXlOIoqVDmLpBiEiq3katvj/2n2mR0SDwtloCew==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2487,17 +2558,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-eF82p0Wrrlt8fQSRL0bGXzK5nWPRV2dYQZdajcfzOD9+cQz9O7ugifrJxclB+xVOvWvagXfqS4Es7vpLP4augw==", "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.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", "semver": "^7.5.4" }, "engines": { @@ -2512,12 +2583,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.15.0.tgz", + "integrity": "sha512-1zvtdC1a9h5Tb5jU9x3ADNXO9yjP8rXlaoChu0DQX40vf5ACVpYIVIZhIMZ6d5sDXH7vq4dsZBT1fEGj8D2n2w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.15.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -3026,12 +3097,12 @@ } }, "node_modules/avl-tree-typed": { - "version": "1.48.3", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.48.3.tgz", - "integrity": "sha512-p81pQU5IzN6rmqRvvuXgebv0yRMl8TrshGBhMfIuvrUTZbQT/mDa4H2s7S8vLl9GXQmomcvPDIbx5qqW998UXQ==", + "version": "1.49.4", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.49.4.tgz", + "integrity": "sha512-koGMepnQ6vmZND5plmUMojmvUSJrbmcFev8uO9XxuJKVKYzcjfWIG3m3Hylantwzi6XAUURFHobmjNgLvsUmaw==", "dev": true, "dependencies": { - "data-structure-typed": "^1.48.3" + "data-structure-typed": "^1.49.4" } }, "node_modules/babel-jest": { @@ -3235,12 +3306,12 @@ } }, "node_modules/binary-tree-typed": { - "version": "1.48.3", - "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.48.3.tgz", - "integrity": "sha512-XKo0ct4dRCNwHj/trT60UaBte8YndIGAetkkTZUv9cNXahGHfZpIHTBgY/RfAoVK0pef6pBNomj/+8RS3p5x1A==", + "version": "1.49.4", + "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.49.4.tgz", + "integrity": "sha512-6f0J37Ab6zb3W1YYlQZ7PIeQp/Nabpc03U93ZGAIZo+mSyIzzXgWZkK0XTvarY5vpv8Pd4u1eDeQjV+n6EHHvQ==", "dev": true, "dependencies": { - "data-structure-typed": "^1.48.3" + "data-structure-typed": "^1.49.4" } }, "node_modules/brace-expansion": { @@ -3319,12 +3390,12 @@ } }, "node_modules/bst-typed": { - "version": "1.48.3", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.48.3.tgz", - "integrity": "sha512-LZJK1h8kf+5OB/N160lPk/BnXP69If92JqvAGR0g0H1kNBKCjkz5aOGQbxpdqcDh08PjUfBbasu7kzv4o1UqPw==", + "version": "1.49.4", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.49.4.tgz", + "integrity": "sha512-qWuWrC5eGm7Czxc5PPXyGP4kRkkz7FOJ4MlwPwo8JQapJwXrxFLj/ix79pqBvQVUZ4AKXPg8vBsqm/hE4M1mkA==", "dev": true, "dependencies": { - "data-structure-typed": "^1.48.3" + "data-structure-typed": "^1.49.4" } }, "node_modules/buffer-from": { @@ -3390,9 +3461,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001571", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz", + "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==", "dev": true, "funding": [ { @@ -3767,9 +3838,9 @@ } }, "node_modules/data-structure-typed": { - "version": "1.48.3", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.48.3.tgz", - "integrity": "sha512-po575Qn2KEIugpS3T86llBLXrY5QGBF6MOwsfbiSHL2iUes6eHjQmQYtKULpU40QE0RKIObd8sV8hrJJ8H328A==", + "version": "1.49.4", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.49.4.tgz", + "integrity": "sha512-Xsb/cHHSFc7x7Rr2ppehqZ+fOI5xykqCZ65rt7tS4n3v0AcNZn1nz9elSwiP7mTHGXCLbOeNQdwLtsmcC32wIw==", "dev": true }, "node_modules/debug": { @@ -4051,9 +4122,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.604", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.604.tgz", - "integrity": "sha512-JAJ4lyLJYudlgJPYJicimU9R+qZ/3iyeyQS99bfT7PWi7psYWeN84lPswTjpHxQueU34PKxM/IJzQS6poYlovQ==", + "version": "1.4.616", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", + "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", "dev": true }, "node_modules/emittery": { @@ -4267,15 +4338,15 @@ } }, "node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", + "@eslint/js": "8.56.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4417,9 +4488,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { "array-includes": "^3.1.7", @@ -4438,7 +4509,7 @@ "object.groupby": "^1.0.1", "object.values": "^1.1.7", "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -4759,9 +4830,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -4886,6 +4957,34 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/format": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", @@ -5088,9 +5187,9 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5264,12 +5363,12 @@ } }, "node_modules/heap-typed": { - "version": "1.48.3", - "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.48.3.tgz", - "integrity": "sha512-K16FfmYL7I5+hmGFiC421fVf9crBTQp46ayP/hg1pC1xo7iBGJXyMNQpkFCaYP0yGyV6PQvue0M7EAzGQOrYbg==", + "version": "1.49.4", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.49.4.tgz", + "integrity": "sha512-ykm0Bs7iYFF16uZ21tnCt+WPBYkLFxWh2HLObZiQmxEgozczcfJpc6IxWfRyvECJkIYrnh2Im9ej4ERWca7+aQ==", "dev": true, "dependencies": { - "data-structure-typed": "^1.48.3" + "data-structure-typed": "^1.49.4" } }, "node_modules/html-escaper": { @@ -5890,6 +5989,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -7781,6 +7898,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8127,6 +8253,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -8278,9 +8429,9 @@ } }, "node_modules/prettier": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", - "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -8862,9 +9013,9 @@ } }, "node_modules/shiki": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz", - "integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", "dev": true, "dependencies": { "ansi-sequence-parser": "^1.1.0", @@ -8984,6 +9135,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -9074,6 +9246,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -9105,14 +9290,14 @@ } }, "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==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "7.1.6", + "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", @@ -9123,7 +9308,16 @@ "sucrase-node": "bin/sucrase-node" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, "node_modules/sucrase/node_modules/commander": { @@ -9136,20 +9330,37 @@ } }, "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==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "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" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9195,9 +9406,9 @@ "dev": true }, "node_modules/terser": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.25.0.tgz", - "integrity": "sha512-we0I9SIsfvNUMP77zC9HG+MylwYYsGFSBG8qm+13oud2Yh+O104y614FRbyjpxys16jZwot72Fpi827YvGzuqg==", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", "dev": true, "peer": true, "dependencies": { @@ -9372,10 +9583,13 @@ "dev": true }, "node_modules/traverse": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", - "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9539,9 +9753,9 @@ } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -9582,9 +9796,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -9936,9 +10150,9 @@ } }, "node_modules/typescript": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", - "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10356,6 +10570,77 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", diff --git a/package.json b/package.json index 81d99c3..6a36ca2 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,12 @@ } }, "scripts": { - "build": "npm run build:mjs && npm run build:cjs && npm run build:umd && npm run build:docs", + "build": "npm run build:mjs && npm run build:cjs && npm run build:umd && npm run build:docs-class", "build:mjs": "rm -rf dist/mjs && tsc -p tsconfig-mjs.json", "build:cjs": "rm -rf dist/cjs && tsc -p tsconfig-cjs.json", "build:umd": "tsup", "build:docs": "typedoc --out docs ./src", + "build:docs-class": "typedoc --out docs ./src/data-structures", "test:unit": "jest --runInBand", "test": "npm run test:unit", "test:integration": "npm run update:subs && jest --config jest.integration.config.js", @@ -87,7 +88,7 @@ "ts-loader": "^9.4.4", "ts-node": "^10.9.1", "tsup": "^7.2.0", - "typedoc": "^0.25.1", + "typedoc": "^0.25.4", "typescript": "^5.3.2" }, "keywords": [ diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 712a5ad..146ab3d 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -2032,43 +2032,6 @@ export class BinaryTree< return newNode; } - /** - * The function `_addTo` adds a new node to a binary tree if there is an available position. - * @param {N | null | undefined} 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 | undefined, parent: BTNKeyOrNode): N | null | undefined { - if (this.isNotNodeInstance(parent)) parent = this.getNode(parent); - - if (parent) { - // 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." - if (parent.left === undefined) { - parent.left = newNode; - if (newNode) { - this._size = this.size + 1; - } - return parent.left; - } else if (parent.right === undefined) { - parent.right = newNode; - if (newNode) { - this._size = this.size + 1; - } - return parent.right; - } else { - return; - } - } else { - return; - } - } - /** * 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. diff --git a/src/data-structures/binary-tree/tree-multimap.ts b/src/data-structures/binary-tree/tree-multimap.ts index f1a5df4..2254e13 100644 --- a/src/data-structures/binary-tree/tree-multimap.ts +++ b/src/data-structures/binary-tree/tree-multimap.ts @@ -361,47 +361,6 @@ export class TreeMultimap< return cloned; } - /** - * Time Complexity: O(1) - constant time, as it performs basic pointer assignments. - * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory. - * - * The function adds a new node to a binary tree, either as the left child or the right child of a - * given parent node. - * @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be - * added to the binary tree. It can be of type `N` (which represents a node in the binary tree) or - * `undefined` if there is no node to add. - * @param {K | N | undefined} parent - The `parent` parameter represents the parent node to - * which the new node will be added as a child. It can be either a node object (`N`) or a key value - * (`K`). - * @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was - * added, or `undefined` if no node was added. - */ - protected override _addTo(newNode: N | undefined, parent: BSTNKeyOrNode): N | undefined { - parent = this.ensureNode(parent); - if (parent) { - if (parent.left === undefined) { - parent.left = newNode; - if (newNode !== undefined) { - this._size = this.size + 1; - this._count += newNode.count; - } - - return parent.left; - } else if (parent.right === undefined) { - parent.right = newNode; - if (newNode !== undefined) { - this._size = this.size + 1; - this._count += newNode.count; - } - return parent.right; - } else { - return; - } - } else { - return; - } - } - /** * The `_swapProperties` function swaps the key, value, count, and height properties between two nodes. * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from diff --git a/src/data-structures/matrix/index.ts b/src/data-structures/matrix/index.ts index e6ec85d..61c9bcb 100644 --- a/src/data-structures/matrix/index.ts +++ b/src/data-structures/matrix/index.ts @@ -1,4 +1,2 @@ export * from './matrix'; -export * from './vector2d'; -export * from './matrix2d'; export * from './navigator'; diff --git a/src/data-structures/matrix/matrix.ts b/src/data-structures/matrix/matrix.ts index 603b3e3..9ad7bd0 100644 --- a/src/data-structures/matrix/matrix.ts +++ b/src/data-structures/matrix/matrix.ts @@ -5,23 +5,452 @@ * @copyright Copyright (c) 2022 Tyler Zeng * @license MIT License */ -// todo need to be improved -export class MatrixNTI2D { - protected readonly _matrix: Array>; + +export class Matrix { + /** + * The constructor function initializes a matrix object with the provided data and options, or with + * default values if no options are provided. + * @param {number[][]} data - A 2D array of numbers representing the data for the matrix. + * @param [options] - The `options` parameter is an optional object that can contain the following + * properties: + */ + constructor( + data: number[][], + options?: { + rows?: number; + cols?: number; + addFn?: (a: number, b: number) => any; + subtractFn?: (a: number, b: number) => any; + multiplyFn?: (a: number, b: number) => any; + } + ) { + if (options) { + const { rows, cols, addFn, subtractFn, multiplyFn } = options; + if (typeof rows === 'number' && rows > 0) this._rows = rows; + else this._rows = data.length; + if (typeof cols === 'number' && cols > 0) this._cols = cols; + else this._cols = data[0]?.length || 0; + if (addFn) this._addFn = addFn; + if (subtractFn) this._subtractFn = subtractFn; + if (multiplyFn) this._multiplyFn = multiplyFn; + } else { + this._rows = data.length; + this._cols = data[0]?.length ?? 0; + } + + if (data.length > 0) { + this._data = data; + } else { + this._data = []; + for (let i = 0; i < this.rows; i++) { + this._data[i] = new Array(this.cols).fill(0); + } + } + } + + protected _rows: number = 0; + + get rows(): number { + return this._rows; + } + + protected _cols: number = 0; + + get cols(): number { + return this._cols; + } + + protected _data: number[][]; + + get data(): number[][] { + return this._data; + } + + get addFn() { + return this._addFn; + } + + get subtractFn() { + return this._subtractFn; + } + + get multiplyFn() { + return this._multiplyFn; + } /** - * The constructor creates a matrix with the specified number of rows and columns, and initializes all elements to a - * given initial value or 0 if not provided. - * @param options - An object containing the following properties: + * The `get` function returns the value at the specified row and column index if it is a valid index. + * @param {number} row - The `row` parameter represents the row index of the element you want to + * retrieve from the data array. + * @param {number} col - The parameter "col" represents the column number of the element you want to + * retrieve from the data array. + * @returns The `get` function returns a number if the provided row and column indices are valid. + * Otherwise, it returns `undefined`. */ - constructor(options: { row: number; col: number; initialVal?: V }) { - const { row, col, initialVal } = options; - this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0)); + get(row: number, col: number): number | undefined { + if (this.isValidIndex(row, col)) { + return this.data[row][col]; + } } - /* The `toArray` method returns the matrix as a two-dimensional array. It converts the internal representation of the - matrix, which is an array of arrays, into a format that is more commonly used in JavaScript. */ - toArray(): Array> { - return this._matrix; + /** + * The set function updates the value at a specified row and column in a two-dimensional array. + * @param {number} row - The "row" parameter represents the row index of the element in a + * two-dimensional array or matrix. It specifies the row where the value will be set. + * @param {number} col - The "col" parameter represents the column index of the element in a + * two-dimensional array. + * @param {number} value - The value parameter represents the number that you want to set at the + * specified row and column in the data array. + * @returns a boolean value. It returns true if the index (row, col) is valid and the value is + * successfully set in the data array. It returns false if the index is invalid and the value is not + * set. + */ + set(row: number, col: number, value: number): boolean { + if (this.isValidIndex(row, col)) { + this.data[row][col] = value; + return true; + } + return false; + } + + /** + * The function checks if the dimensions of the given matrix match the dimensions of the current + * matrix. + * @param {Matrix} matrix - The parameter `matrix` is of type `Matrix`. + * @returns a boolean value. + */ + isMatchForCalculate(matrix: Matrix): boolean { + return this.rows === matrix.rows && this.cols === matrix.cols; + } + + /** + * The `add` function adds two matrices together, returning a new matrix with the result. + * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. + * @returns The `add` method returns a new `Matrix` object that represents the result of adding the + * current matrix with the provided `matrix` parameter. + */ + add(matrix: Matrix): Matrix | undefined { + if (!this.isMatchForCalculate(matrix)) { + throw new Error('Matrix dimensions must match for addition.'); + } + + const resultData: number[][] = []; + for (let i = 0; i < this.rows; i++) { + resultData[i] = []; + for (let j = 0; j < this.cols; j++) { + const a = this.get(i, j), + b = matrix.get(i, j); + if (a !== undefined && b !== undefined) { + const added = this._addFn(a, b); + if (added) { + resultData[i][j] = added; + } + } + } + } + + return new Matrix(resultData, { + rows: this.rows, + cols: this.cols, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + } + + /** + * The `subtract` function performs element-wise subtraction between two matrices and returns a new + * matrix with the result. + * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. It + * represents the matrix that you want to subtract from the current matrix. + * @returns a new Matrix object with the result of the subtraction operation. + */ + subtract(matrix: Matrix): Matrix | undefined { + if (!this.isMatchForCalculate(matrix)) { + throw new Error('Matrix dimensions must match for subtraction.'); + } + + const resultData: number[][] = []; + for (let i = 0; i < this.rows; i++) { + resultData[i] = []; + for (let j = 0; j < this.cols; j++) { + const a = this.get(i, j), + b = matrix.get(i, j); + if (a !== undefined && b !== undefined) { + const subtracted = this._subtractFn(a, b); + if (subtracted) { + resultData[i][j] = subtracted; + } + } + } + } + + return new Matrix(resultData, { + rows: this.rows, + cols: this.cols, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + } + + /** + * The `multiply` function performs matrix multiplication between two matrices and returns the result + * as a new matrix. + * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. + * @returns a new Matrix object. + */ + multiply(matrix: Matrix): Matrix | undefined { + if (this.cols !== matrix.rows) { + throw new Error('Matrix dimensions must be compatible for multiplication (A.cols = B.rows).'); + } + + const resultData: number[][] = []; + for (let i = 0; i < this.rows; i++) { + resultData[i] = []; + for (let j = 0; j < matrix.cols; j++) { + let sum: number | undefined; + for (let k = 0; k < this.cols; k++) { + const a = this.get(i, k), + b = matrix.get(k, j); + if (a !== undefined && b !== undefined) { + const multiplied = this.multiplyFn(a, b); + if (multiplied !== undefined) { + sum = this.addFn(sum, multiplied); + } + } + } + if (sum !== undefined) resultData[i][j] = sum; + } + } + + return new Matrix(resultData, { + rows: this.rows, + cols: matrix.cols, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + } + + /** + * The transpose function takes a matrix and returns a new matrix that is the transpose of the + * original matrix. + * @returns The transpose() function returns a new Matrix object with the transposed data. + */ + transpose(): Matrix { + if (this.data.some(row => row.length !== this.rows)) { + throw new Error('Matrix must be rectangular for transposition.'); + } + + const resultData: number[][] = []; + + for (let j = 0; j < this.cols; j++) { + resultData[j] = []; + for (let i = 0; i < this.rows; i++) { + const trans = this.get(i, j); + if (trans !== undefined) resultData[j][i] = trans; + } + } + + return new Matrix(resultData, { + rows: this.cols, + cols: this.rows, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + } + + /** + * The `inverse` function calculates the inverse of a square matrix using Gaussian elimination. + * @returns a Matrix object, which represents the inverse of the original matrix. + */ + inverse(): Matrix | undefined { + // Check if the matrix is square + if (this.rows !== this.cols) { + throw new Error('Matrix must be square for inversion.'); + } + + // Create an augmented matrix [this | I] + const augmentedMatrixData: number[][] = []; + for (let i = 0; i < this.rows; i++) { + augmentedMatrixData[i] = this.data[i].slice(); // Copy the original matrix + for (let j = 0; j < this.cols; j++) { + augmentedMatrixData[i][this.cols + j] = i === j ? 1 : 0; // Append the identity matrix + } + } + + const augmentedMatrix = new Matrix(augmentedMatrixData, { + rows: this.rows, + cols: this.cols * 2, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + + // Apply Gaussian elimination to transform the left half into the identity matrix + for (let i = 0; i < this.rows; i++) { + // Find pivot + let pivotRow = i; + while (pivotRow < this.rows && augmentedMatrix.get(pivotRow, i) === 0) { + pivotRow++; + } + + if (pivotRow === this.rows) { + // Matrix is singular, and its inverse does not exist + throw new Error('Matrix is singular, and its inverse does not exist.'); + } + + // Swap rows to make the pivot the current row + augmentedMatrix._swapRows(i, pivotRow); + + // Scale the pivot row to make the pivot element 1 + const pivotElement = augmentedMatrix.get(i, i) ?? 1; + + if (pivotElement === 0) { + // Handle division by zero + throw new Error('Matrix is singular, and its inverse does not exist (division by zero).'); + } + + augmentedMatrix._scaleRow(i, 1 / pivotElement); + + // Eliminate other rows to make elements in the current column zero + for (let j = 0; j < this.rows; j++) { + if (j !== i) { + let factor = augmentedMatrix.get(j, i); + if (factor === undefined) factor = 0; + + augmentedMatrix._addScaledRow(j, i, -factor); + } + } + } + + // Extract the right half of the augmented matrix as the inverse + const inverseData: number[][] = []; + for (let i = 0; i < this.rows; i++) { + inverseData[i] = augmentedMatrix.data[i].slice(this.cols); + } + + return new Matrix(inverseData, { + rows: this.rows, + cols: this.cols, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + } + + /** + * The dot function calculates the dot product of two matrices and returns a new matrix. + * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. + * @returns a new Matrix object. + */ + dot(matrix: Matrix): Matrix | undefined { + if (this.cols !== matrix.rows) { + throw new Error( + 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.' + ); + } + + const resultData: number[][] = []; + for (let i = 0; i < this.rows; i++) { + resultData[i] = []; + for (let j = 0; j < matrix.cols; j++) { + let sum: number | undefined; + for (let k = 0; k < this.cols; k++) { + const a = this.get(i, k), + b = matrix.get(k, j); + if (a !== undefined && b !== undefined) { + const multiplied = this.multiplyFn(a, b); + if (multiplied !== undefined) { + sum = this.addFn(sum, multiplied); + } + } + } + if (sum !== undefined) resultData[i][j] = sum; + } + } + + return new Matrix(resultData, { + rows: this.rows, + cols: matrix.cols, + addFn: this.addFn, + subtractFn: this.subtractFn, + multiplyFn: this.multiplyFn + }); + } + + protected _addFn(a: number | undefined, b: number): number | undefined { + if (a === undefined) return b; + return a + b; + } + + protected _subtractFn(a: number, b: number) { + return a - b; + } + + protected _multiplyFn(a: number, b: number) { + return a * b; + } + + /** + * The function checks if a given row and column index is valid within a specified range. + * @param {number} row - The `row` parameter represents the row index of a two-dimensional array or + * matrix. It is a number that indicates the specific row in the matrix. + * @param {number} col - The "col" parameter represents the column index in a two-dimensional array + * or grid. It is used to check if the given column index is valid within the bounds of the grid. + * @returns A boolean value is being returned. + */ + protected isValidIndex(row: number, col: number): boolean { + return row >= 0 && row < this.rows && col >= 0 && col < this.cols; + } + + /** + * The function `_swapRows` swaps the positions of two rows in an array. + * @param {number} row1 - The `row1` parameter is the index of the first row that you want to swap. + * @param {number} row2 - The `row2` parameter is the index of the second row that you want to swap + * with the first row. + */ + protected _swapRows(row1: number, row2: number): void { + const temp = this.data[row1]; + this.data[row1] = this.data[row2]; + this.data[row2] = temp; + } + + /** + * The function scales a specific row in a matrix by a given scalar value. + * @param {number} row - The `row` parameter represents the index of the row in the matrix that you + * want to scale. It is a number that indicates the position of the row within the matrix. + * @param {number} scalar - The scalar parameter is a number that is used to multiply each element in + * a specific row of a matrix. + */ + protected _scaleRow(row: number, scalar: number): void { + for (let j = 0; j < this.cols; j++) { + let multiplied = this.multiplyFn(this.data[row][j], scalar); + if (multiplied === undefined) multiplied = 0; + this.data[row][j] = multiplied; + } + } + + /** + * The function `_addScaledRow` multiplies a row in a matrix by a scalar value and adds it to another + * row. + * @param {number} targetRow - The targetRow parameter represents the index of the row in which the + * scaled values will be added. + * @param {number} sourceRow - The sourceRow parameter represents the index of the row from which the + * values will be scaled and added to the targetRow. + * @param {number} scalar - The scalar parameter is a number that is used to scale the values in the + * source row before adding them to the target row. + */ + protected _addScaledRow(targetRow: number, sourceRow: number, scalar: number): void { + for (let j = 0; j < this.cols; j++) { + let multiplied = this.multiplyFn(this.data[sourceRow][j], scalar); + if (multiplied === undefined) multiplied = 0; + const scaledValue = multiplied; + let added = this.addFn(this.data[targetRow][j], scaledValue); + if (added === undefined) added = 0; + this.data[targetRow][j] = added; + } } } diff --git a/src/data-structures/matrix/matrix2d.ts b/src/data-structures/matrix/matrix2d.ts deleted file mode 100644 index beb0991..0000000 --- a/src/data-structures/matrix/matrix2d.ts +++ /dev/null @@ -1,211 +0,0 @@ -/** - * data-structure-typed - * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng - * @license MIT License - */ -import { Vector2D } from './vector2d'; - -export class Matrix2D { - protected readonly _matrix: number[][]; - - /** - * The constructor function initializes a Matrix2D object with either a default identity matrix, or a provided matrix - * or Vector2D object. - * @param {number[][] | Vector2D} [value] - The `value` parameter can be either a 2D array of numbers (`number[][]`) or - * an instance of the `Vector2D` class. - */ - constructor(value?: number[][] | Vector2D) { - if (typeof value === 'undefined') { - this._matrix = Matrix2D.identity; - } else if (value instanceof Vector2D) { - this._matrix = Matrix2D.identity; - this._matrix[0][0] = value.x; - this._matrix[1][0] = value.y; - this._matrix[2][0] = value.w; - } else { - this._matrix = value; - } - } - - /** - * The function returns a 2D array with three empty arrays. - * @returns An empty 2-dimensional array with 3 empty arrays inside. - */ - static get empty(): number[][] { - return [[], [], []]; - } - - /** - * The above function returns a 3x3 identity matrix. - * @returns The method is returning a 2-dimensional array of numbers representing the identity matrix. - */ - static get identity(): number[][] { - return [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1] - ]; - } - - /** - * The function returns a two-dimensional array of numbers. - * @returns The getter method is returning the value of the private variable `_matrix`, which is a two-dimensional - * array of numbers. - */ - get m(): number[][] { - return this._matrix; - } - - /** - * The function takes two 2D matrices as input and returns their sum as a new 2D matrix. - * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to be added. - * @param {Matrix2D} matrix2 - The parameter `matrix2` is a Matrix2D object. - * @returns a new instance of the Matrix2D class, which is created using the result array. - */ - static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D { - const result = Matrix2D.empty; - for (let i = 0; i < 3; i++) { - for (let j = 0; j < 3; j++) { - result[i][j] = matrix1.m[i][j] + matrix2.m[i][j]; - } - } - return new Matrix2D(result); - } - - /** - * The function subtracts two 2D matrices and returns the result as a new Matrix2D object. - * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to subtract from. - * @param {Matrix2D} matrix2 - Matrix2D is a class representing a 2D matrix. It has a property `m` which is a 2D array - * representing the matrix elements. - * @returns a new instance of the Matrix2D class, which is created using the result array. - */ - static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D { - const result = Matrix2D.empty; - for (let i = 0; i < 3; i++) { - for (let j = 0; j < 3; j++) { - result[i][j] = matrix1.m[i][j] - matrix2.m[i][j]; - } - } - return new Matrix2D(result); - } - - /** - * The function multiplies two 2D matrices and returns the result as a new Matrix2D object. - * @param {Matrix2D} matrix1 - A 2D matrix represented by the Matrix2D class. - * @param {Matrix2D} matrix2 - The parameter `matrix2` is a 2D matrix of size 3x3. - * @returns a new instance of the Matrix2D class, created using the result array. - */ - static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D { - const result = Matrix2D.empty; - for (let i = 0; i < 3; i++) { - for (let j = 0; j < 3; j++) { - result[i][j] = 0; - for (let k = 0; k < 3; k++) { - result[i][j] += matrix1.m[i][k] * matrix2.m[k][j]; - } - } - } - return new Matrix2D(result); - } - - /** - * The function multiplies each element of a 2D matrix by a given value and returns the resulting matrix. - * @param {Matrix2D} matrix - The `matrix` parameter is an instance of the `Matrix2D` class, which represents a 2D - * matrix. It contains a property `m` that is a 2D array representing the matrix elements. - * @param {number} value - The `value` parameter is a number that you want to multiply each element of the `matrix` by. - * @returns a new instance of the Matrix2D class, which is created using the result array. - */ - static multiplyByValue(matrix: Matrix2D, value: number): Matrix2D { - const result = Matrix2D.empty; - for (let i = 0; i < 3; i++) { - for (let j = 0; j < 3; j++) { - result[i][j] = matrix.m[i][j] * value; - } - } - return new Matrix2D(result); - } - - /** - * The function multiplies a 2D matrix by a 2D vector and returns the result as a 2D vector. - * @param {Matrix2D} matrix - The parameter "matrix" is of type Matrix2D. It represents a 2-dimensional matrix. - * @param {Vector2D} vector - The "vector" parameter is a 2D vector, represented by an object of type Vector2D. - * @returns a Vector2D. - */ - static multiplyByVector(matrix: Matrix2D, vector: Vector2D): Vector2D { - const resultMatrix = Matrix2D.multiply(matrix, new Matrix2D(vector)); - return resultMatrix.toVector(); - } - - /** - * The function returns a 2D matrix that scales and flips a vector around the center of a given width and height. - * @param {number} width - The width parameter represents the width of the view or the canvas. It is a number that - * specifies the width in pixels or any other unit of measurement. - * @param {number} height - The height parameter represents the height of the view or the canvas. It is used to - * calculate the centerY value, which is the vertical center of the view. - * @returns a Matrix2D object. - */ - static view(width: number, height: number): Matrix2D { - const scaleStep = 1; // Scale every vector * scaleStep - const centerX = width / 2; - const centerY = height / 2; - const flipX = Math.cos(Math.PI); // rotate 180deg / 3.14radian around X-axis - - return new Matrix2D([ - [scaleStep, 0, centerX], - [0, flipX * scaleStep, centerY], - [0, 0, 1] - ]); - } - - /** - * The function scales a matrix by a given factor. - * @param {number} factor - The factor parameter is a number that represents the scaling factor by which the matrix - * should be scaled. - * @returns the result of multiplying a new instance of Matrix2D by the given factor. - */ - static scale(factor: number) { - return Matrix2D.multiplyByValue(new Matrix2D(), factor); - } - - /** - * The function "rotate" takes an angle in radians and returns a 2D transformation matrix for rotating objects. - * @param {number} radians - The "radians" parameter is the angle in radians by which you want to rotate an object. - * @returns The code is returning a new instance of a Matrix2D object. - */ - static rotate(radians: number) { - const cos = Math.cos(radians); - const sin = Math.sin(radians); - - return new Matrix2D([ - [cos, -sin, 0], - [sin, cos, 0], - [0, 0, 1] - ]); - } - - /** - * The translate function takes a 2D vector and returns a 2D matrix that represents a translation transformation. - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D. It represents a 2D vector with components x - * and y, and an optional w component. - * @returns The method is returning a new instance of the Matrix2D class. - */ - static translate(vector: Vector2D): Matrix2D { - return new Matrix2D([ - [1, 0, vector.x], - [0, 1, vector.y], - [0, 0, vector.w] - ]); - } - - /** - * The function "toVector" returns a new Vector2D object with the values from the first and second elements of the - * _matrix array. - * @returns A new instance of the Vector2D class is being returned. The values of the returned vector are taken from - * the first column of the matrix. - */ - toVector(): Vector2D { - return new Vector2D(this._matrix[0][0], this._matrix[1][0]); - } -} diff --git a/src/data-structures/matrix/vector2d.ts b/src/data-structures/matrix/vector2d.ts deleted file mode 100644 index 2f62f4e..0000000 --- a/src/data-structures/matrix/vector2d.ts +++ /dev/null @@ -1,315 +0,0 @@ -/** - * data-structure-typed - * - * @author Tyler Zeng - * @copyright Copyright (c) 2022 Tyler Zeng - * @license MIT License - */ -export class Vector2D { - constructor( - public x: number = 0, - public y: number = 0, - public w: number = 1 // needed for matrix multiplication - ) { - } - - /** - * The function checks if the x and y values of a point are both zero. - * @returns A boolean value indicating whether both the x and y properties of the object are equal to 0. - */ - get isZero(): boolean { - return this.x === 0 && this.y === 0; - } - - /** - * The above function calculates the length of a vector using the Pythagorean theorem. - * @returns The length of a vector, calculated using the Pythagorean theorem. - */ - get length(): number { - return Math.sqrt(this.x * this.x + this.y * this.y); - } - - /** - * The function calculates the square of the length of a vector. - * @returns The method is returning the sum of the squares of the x and y values. - */ - get lengthSq(): number { - return this.x * this.x + this.y * this.y; - } - - /** - * The "rounded" function returns a new Vector2D object with the x and y values rounded to the nearest whole number. - * @returns The method is returning a new instance of the Vector2D class with the x and y values rounded to the nearest - * whole number. - */ - get rounded(): Vector2D { - return new Vector2D(Math.round(this.x), Math.round(this.y)); - } - - /** - * The function "add" takes two Vector2D objects as parameters and returns a new Vector2D object with the sum of their - * x and y components. - * @param {Vector2D} vector1 - The parameter `vector1` is an instance of the `Vector2D` class. It represents a - * 2-dimensional vector with an `x` and `y` component. - * @param {Vector2D} vector2 - The parameter "vector2" is of type Vector2D. It represents a 2-dimensional vector with - * an x and y component. - * @returns The method is returning a new instance of the Vector2D class with the x and y components of the two input - * vectors added together. - */ - static add(vector1: Vector2D, vector2: Vector2D): Vector2D { - return new Vector2D(vector1.x + vector2.x, vector1.y + vector2.y); - } - - /** - * The subtract function takes two Vector2D objects as parameters and returns a new Vector2D object with the x and y - * components subtracted. - * @param {Vector2D} vector1 - The parameter `vector1` is an instance of the `Vector2D` class, representing a - * 2-dimensional vector. It has properties `x` and `y` which represent the x and y components of the vector - * respectively. - * @param {Vector2D} vector2 - The parameter "vector2" is a Vector2D object. It represents the second vector that you - * want to subtract from the first vector. - * @returns The method is returning a new Vector2D object with the x and y components subtracted from vector1 and - * vector2. - */ - static subtract(vector1: Vector2D, vector2: Vector2D): Vector2D { - return new Vector2D(vector1.x - vector2.x, vector1.y - vector2.y); - } - - /** - * The function subtracts a given value from the x and y components of a Vector2D object and returns a new Vector2D - * object. - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D, which represents a 2-dimensional vector with - * x and y components. - * @param {number} value - The "value" parameter is a number that will be subtracted from both the x and y components - * of the "vector" parameter. - * @returns A new Vector2D object with the x and y values subtracted by the given value. - */ - static subtractValue(vector: Vector2D, value: number): Vector2D { - return new Vector2D(vector.x - value, vector.y - value); - } - - /** - * The function multiplies a Vector2D object by a given value. - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D, which represents a 2-dimensional vector with - * x and y components. - * @param {number} value - The "value" parameter is a number that represents the value by which the x and y components - * of the vector will be multiplied. - * @returns A new Vector2D object with the x and y values multiplied by the given value. - */ - static multiply(vector: Vector2D, value: number): Vector2D { - return new Vector2D(vector.x * value, vector.y * value); - } - - /** - * The function divides the x and y components of a Vector2D by a given value and returns a new Vector2D. - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D, which represents a 2-dimensional vector with - * x and y components. - * @param {number} value - The value parameter is a number that will be used to divide the x and y components of the - * vector. - * @returns A new instance of the Vector2D class with the x and y values divided by the given value. - */ - static divide(vector: Vector2D, value: number): Vector2D { - return new Vector2D(vector.x / value, vector.y / value); - } - - /** - * The function checks if two Vector2D objects are equal by comparing their x and y values. - * @param {Vector2D} vector1 - The parameter `vector1` is of type `Vector2D`, which represents a 2-dimensional vector. - * It has two properties: `x` and `y`, which represent the x and y components of the vector, respectively. - * @param {Vector2D} vector2 - The parameter "vector2" is of type Vector2D. - * @returns a boolean value, which indicates whether the two input vectors are equal or not. - */ - static equals(vector1: Vector2D, vector2: Vector2D): boolean { - return vector1.x === vector2.x && vector1.y === vector2.y; - } - - /** - * The function checks if two Vector2D objects are equal within a specified rounding factor. - * @param {Vector2D} vector1 - The first vector to compare. - * @param {Vector2D} vector2 - The parameter "vector2" is a Vector2D object, which represents a 2-dimensional vector. - * It is used as one of the inputs for the "equalsRounded" function. - * @param [roundingFactor=12] - The roundingFactor parameter is used to determine the threshold for considering two - * vectors as equal. If the absolute difference in the x and y components of the vectors is less than the - * roundingFactor, the vectors are considered equal. - * @returns a boolean value. - */ - static equalsRounded(vector1: Vector2D, vector2: Vector2D, roundingFactor = 12): boolean { - const vector = Vector2D.abs(Vector2D.subtract(vector1, vector2)); - if (vector.x < roundingFactor && vector.y < roundingFactor) { - return true; - } - - return false; - } - - /** - * The normalize function takes a vector as input and returns a normalized version of the vector.Normalizes the vector if it matches a certain condition - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D. - * @returns the normalized vector if its length is greater than a very small value (epsilon), otherwise it returns the - * original vector. - */ - static normalize(vector: Vector2D): Vector2D { - const length = vector.length; - if (length > 2.220446049250313e-16) { - // Epsilon - return Vector2D.divide(vector, length); - } - - return vector; - } - - /** - * The function truncates a vector to a maximum length if it exceeds that length.Adjusts x and y so that the length of the vector does not exceed max - * @param {Vector2D} vector - A 2D vector represented by the Vector2D class. - * @param {number} max - The `max` parameter is a number that represents the maximum length that the `vector` should - * have. - * @returns either the original vector or a truncated version of the vector, depending on whether the length of the - * vector is greater than the maximum value specified. - */ - static truncate(vector: Vector2D, max: number): Vector2D { - if (vector.length > max) { - return Vector2D.multiply(Vector2D.normalize(vector), max); - } - - return vector; - } - - /** - * The function returns a new Vector2D object that is perpendicular to the input vector.The vector that is perpendicular to this one - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D. - * @returns A new Vector2D object is being returned. - */ - static perp(vector: Vector2D): Vector2D { - return new Vector2D(-vector.y, vector.x); - } - - /** - * The reverse function takes a Vector2D object and returns a new Vector2D object with the negated x and y values. - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D, which represents a 2-dimensional vector. It - * has two properties: "x" and "y", which represent the x and y components of the vector, respectively. - * @returns A new Vector2D object with the negated x and y values of the input vector. Returns the vector that is the reverse of this vector - */ - static reverse(vector: Vector2D): Vector2D { - return new Vector2D(-vector.x, -vector.y); - } - - /** - * The function takes a Vector2D object as input and returns a new Vector2D object with the absolute values of its x - * and y components. - * @param {Vector2D} vector - The parameter "vector" is of type Vector2D, which represents a 2-dimensional vector. It - * has two properties: "x" and "y", which represent the x and y components of the vector, respectively. - * @returns The method is returning a new Vector2D object with the absolute values of the x and y components of the - * input vector. - */ - static abs(vector: Vector2D): Vector2D { - return new Vector2D(Math.abs(vector.x), Math.abs(vector.y)); - } - - /** - * The dot function calculates the dot product of two 2D vectors.The dot product of v1 and v2 - * @param {Vector2D} vector1 - The parameter `vector1` represents a 2D vector with its x and y components. - * @param {Vector2D} vector2 - The "vector2" parameter is a Vector2D object. It represents a two-dimensional vector - * with an x and y component. - * @returns The dot product of the two input vectors. - */ - static dot(vector1: Vector2D, vector2: Vector2D): number { - return vector1.x * vector2.x + vector1.y * vector2.y; - } - - // /** - // * Transform vectors based on the current tranformation matrices: translation, rotation and scale - // * @param vectors The vectors to transform - // */ - // static transform(vector: Vector2D, transformation: Matrix2D): Vector2D { - // return Matrix2D.multiplyByVector(transformation, vector) - // } - - // /** - // * Transform vectors based on the current tranformation matrices: translation, rotation and scale - // * @param vectors The vectors to transform - // */ - // static transformList(vectors: Vector2D[], transformation: Matrix2D): Vector2D[] { - // return vectors.map(vector => Matrix2D.multiplyByVector(transformation, vector)) - // } - - /** - * The function calculates the distance between two points in a two-dimensional space. - * @param {Vector2D} vector1 - The parameter `vector1` represents the first vector in 2D space, while `vector2` - * represents the second vector. Each vector has an `x` and `y` component, which represent their respective coordinates - * in the 2D space. - * @param {Vector2D} vector2 - The `vector2` parameter represents the second vector in the calculation of distance. It - * is an instance of the `Vector2D` class, which typically has properties `x` and `y` representing the coordinates of - * the vector in a 2D space. - * @returns The distance between vector1 and vector2. - */ - static distance(vector1: Vector2D, vector2: Vector2D): number { - const ySeparation = vector2.y - vector1.y; - const xSeparation = vector2.x - vector1.x; - return Math.sqrt(ySeparation * ySeparation + xSeparation * xSeparation); - } - - /** - * The function calculates the squared distance between two 2D vectors. - * @param {Vector2D} vector1 - The parameter `vector1` represents the first vector, which is an instance of the - * `Vector2D` class. It contains the x and y coordinates of the vector. - * @param {Vector2D} vector2 - The `vector2` parameter represents the second vector in a two-dimensional space. It has - * properties `x` and `y` which represent the coordinates of the vector. - * @returns the square of the distance between the two input vectors. - */ - static distanceSq(vector1: Vector2D, vector2: Vector2D): number { - const ySeparation = vector2.y - vector1.y; - const xSeparation = vector2.x - vector1.x; - return ySeparation * ySeparation + xSeparation * xSeparation; - } - - /** - * The sign function determines the sign of the cross product between two 2D vectors. - * (assuming the Y axis is pointing down, X axis to right like a Window app) - * @param {Vector2D} vector1 - The parameter `vector1` is of type `Vector2D`, which represents a 2-dimensional vector. - * It likely has properties `x` and `y` representing the x and y components of the vector, respectively. - * @param {Vector2D} vector2 - The above code defines a function called "sign" that takes two parameters: vector1 and - * vector2. Both vector1 and vector2 are of type Vector2D. - * @returns either -1 or 1. Returns positive if v2 is clockwise of this vector, negative if counterclockwise - */ - static sign(vector1: Vector2D, vector2: Vector2D): number { - if (vector1.y * vector2.x > vector1.x * vector2.y) { - return -1; - } - - return 1; - } - - /** - * The function calculates the angle between a given vector and the negative y-axis. - * @param {Vector2D} vector - The "vector" parameter is an instance of the Vector2D class, which represents a - * 2-dimensional vector. It has two properties: "x" and "y", which represent the x and y components of the vector, - * respectively. - * @returns the angle between the given vector and the vector (0, -1) in radians.Returns the angle between origin and the given vector in radians - */ - static angle(vector: Vector2D): number { - const origin = new Vector2D(0, -1); - const radian = Math.acos(Vector2D.dot(vector, origin) / (vector.length * origin.length)); - return Vector2D.sign(vector, origin) === 1 ? Math.PI * 2 - radian : radian; - } - - /** - * The function "random" generates a random Vector2D object with x and y values within the specified range. - * @param {number} maxX - The maxX parameter represents the maximum value for the x-coordinate of the random vector. - * @param {number} maxY - The `maxY` parameter represents the maximum value for the y-coordinate of the generated - * random vector. - * @returns a new instance of the Vector2D class with random x and y values. - */ - static random(maxX: number, maxY: number): Vector2D { - const randX = Math.floor(Math.random() * maxX - maxX / 2); - const randY = Math.floor(Math.random() * maxY - maxY / 2); - return new Vector2D(randX, randY); - } - - /** - * The function sets the values of x and y to zero. - */ - zero(): void { - this.x = 0; - this.y = 0; - } -} diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 3d2732c..0ca8482 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -100,3 +100,8 @@ export const isWeakKey = (input: unknown): input is object => { export const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) => Math.floor((totalQuantity + unitSize - 1) / unitSize); + +export const roundFixed = (num: number, digit: number = 10) => { + const multiplier = Math.pow(10, digit); + return Math.round(num * multiplier) / multiplier; +}; diff --git a/test/integration/bst.test.ts b/test/integration/bst.test.ts index 7511581..e954728 100644 --- a/test/integration/bst.test.ts +++ b/test/integration/bst.test.ts @@ -7,7 +7,7 @@ describe('Individual package BST operations test', () => { bst.add([11, 11]); bst.add([3, 3]); const idsOrValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; - bst.addMany(idsOrValues, false); + bst.addMany(idsOrValues, undefined); expect(bst.root).toBeInstanceOf(BSTNode); if (bst.root) expect(bst.root.key).toBe(11); @@ -204,7 +204,7 @@ describe('Individual package BST operations test', () => { [5, { key: 5, keyA: 5 }] ]; - objBST.addMany(values, false); + objBST.addMany(values, undefined); expect(objBST.root).toBeInstanceOf(BSTNode); diff --git a/test/unit/data-structures/matrix/matrix.test.ts b/test/unit/data-structures/matrix/matrix.test.ts index 84e38ef..7e99e3a 100644 --- a/test/unit/data-structures/matrix/matrix.test.ts +++ b/test/unit/data-structures/matrix/matrix.test.ts @@ -1,54 +1,347 @@ -import { MatrixNTI2D } from '../../../../src'; +import { Matrix } from '../../../../src'; -describe('MatrixNTI2D', () => { - it('should initialize a matrix with rows and columns', () => { - const numRows = 3; - const numCols = 4; - const matrix = new MatrixNTI2D({ row: numRows, col: numCols }); +describe('Matrix', () => { + let matrix: Matrix; - expect(matrix.toArray().length).toBe(numRows); - expect(matrix.toArray()[0].length).toBe(numCols); + beforeEach(() => { + // Initialize a 3x3 matrix with zeros + matrix = new Matrix([ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ]); }); - it('should initialize all elements with the provided initial value', () => { - const numRows = 3; - const numCols = 4; - const initialValue = 42; - const matrix = new MatrixNTI2D({ row: numRows, col: numCols, initialVal: initialValue }); - - const matrixArray = matrix.toArray(); - for (let i = 0; i < numRows; i++) { - for (let j = 0; j < numCols; j++) { - expect(matrixArray[i][j]).toBe(initialValue); - } - } + it('should create a matrix with the correct dimensions and initial values', () => { + expect(matrix.rows).toBe(3); + expect(matrix.cols).toBe(3); + expect(matrix.data).toEqual([ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ]); }); - it('should initialize all elements with 0 if no initial value is provided', () => { - const numRows = 3; - const numCols = 4; - const matrix = new MatrixNTI2D({ row: numRows, col: numCols }); - - const matrixArray = matrix.toArray(); - for (let i = 0; i < numRows; i++) { - for (let j = 0; j < numCols; j++) { - expect(matrixArray[i][j]).toBe(0); - } - } + it('should get a value at a specific position', () => { + expect(matrix.get(1, 1)).toBe(0); + expect(matrix.get(2, 2)).toBe(0); }); - it('should convert the matrix to a two-dimensional array', () => { - const numRows = 2; - const numCols = 3; - const matrix = new MatrixNTI2D({ row: numRows, col: numCols, initialVal: 1 }); + it('should set a value at a specific position', () => { + matrix.set(1, 1, 42); + expect(matrix.get(1, 1)).toBe(42); + }); - const matrixArray = matrix.toArray(); - expect(matrixArray.length).toBe(numRows); - for (let i = 0; i < numRows; i++) { - expect(matrixArray[i].length).toBe(numCols); - for (let j = 0; j < numCols; j++) { - expect(matrixArray[i][j]).toBe(1); - } - } + it('should not allow getting or setting values at invalid positions', () => { + expect(matrix.get(-1, 0)).toBeUndefined(); + expect(matrix.get(0, 10)).toBeUndefined(); + + const originalValue = matrix.get(1, 1); + matrix.set(-1, 1, 42); + matrix.set(1, 10, 42); + expect(matrix.get(1, 1)).toBe(originalValue); + }); + + describe('add', () => { + it('should add two matrices correctly', () => { + const matrixA = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrixB = new Matrix([ + [5, 6], + [7, 8] + ]); + const expectedResult = new Matrix([ + [6, 8], + [10, 12] + ]); + + const result = matrixA.add(matrixB); + + expect(result?.data).toEqual(expectedResult.data); + }); + + it('should throw an error for matrices with mismatched dimensions', () => { + const matrixA = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrixB = new Matrix([ + [5, 6, 7], + [8, 9, 10] + ]); + + expect(() => matrixA.add(matrixB)).toThrowError('Matrix dimensions must match for addition.'); + }); + + it('should throw an error for matrices with mismatched dimensions', () => { + const matrixA = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrixB = new Matrix([ + [5, 6, 7], + [8, 9, 10] + ]); + + expect(() => matrixA.add(matrixB)).toThrowError('Matrix dimensions must match for addition.'); + }); + }); + + describe('subtract', () => { + it('should subtract two matrices with numbers correctly', () => { + const matrixA = new Matrix([ + [5, 6], + [7, 8] + ]); + const matrixB = new Matrix([ + [1, 2], + [3, 4] + ]); + const expectedResult = new Matrix([ + [4, 4], + [4, 4] + ]); + + const result = matrixA.subtract(matrixB); + + expect(result?.data).toEqual(expectedResult.data); + }); + + it('should subtract two matrices with custom subtract function correctly', () => { + const customSubtractFn = (a: number, b: number) => a * 10 - b; // Custom subtraction for arrays + const matrixA = new Matrix( + [ + [5, 6], + [7, 8] + ], + { subtractFn: customSubtractFn } + ); + const matrixB = new Matrix( + [ + [1, 2], + [3, 4] + ], + { subtractFn: customSubtractFn } + ); + const expectedResult = new Matrix( + [ + [49, 58], + [67, 76] + ], + { subtractFn: customSubtractFn } + ); + + const result = matrixA.subtract(matrixB); + + expect(result?.data).toEqual(expectedResult.data); + }); + + it('should throw an error for matrices with mismatched dimensions', () => { + const matrixA = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrixB = new Matrix([ + [5, 6, 7], + [8, 9, 10] + ]); + + expect(() => matrixA.subtract(matrixB)).toThrowError('Matrix dimensions must match for subtraction.'); + }); + }); + + describe('multiply', () => { + it('should multiply two matrices with numbers correctly', () => { + const matrixA = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrixB = new Matrix([ + [5, 6], + [7, 8] + ]); + const expectedResult = new Matrix([ + [19, 22], + [43, 50] + ]); + + const result = matrixA.multiply(matrixB); + + expect(result?.data).toEqual(expectedResult.data); + }); + + it('should multiply two matrices with custom multiply function correctly', () => { + const customMultiplyFn = (a: number, b: number) => a * 10 * b; // Custom multiplication for arrays + const matrixA = new Matrix( + [ + [1, 2], + [3, 4] + ], + { multiplyFn: customMultiplyFn } + ); + const matrixB = new Matrix( + [ + [5, 6], + [7, 8] + ], + { multiplyFn: customMultiplyFn } + ); + const result = matrixA.multiply(matrixB); + + expect(result?.data).toEqual([ + [190, 220], + [430, 500] + ]); + }); + + it('should throw an error for matrices with mismatched dimensions', () => { + const matrixA = new Matrix([ + [1, 2, 3], + [3, 4, 5] + ]); + const matrixB = new Matrix([ + [5, 6, 7], + [8, 9, 1] + ]); + + expect(() => matrixA.multiply(matrixB)).toThrowError( + 'Matrix dimensions must be compatible for multiplication (A.cols = B.rows).' + ); + }); + }); + + describe('transpose', () => { + test('should transpose a matrix with numeric values correctly', () => { + const originalMatrix = new Matrix([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ]); + + const transposedMatrix = originalMatrix.transpose(); + + expect(transposedMatrix.rows).toBe(originalMatrix.cols); + expect(transposedMatrix.cols).toBe(originalMatrix.rows); + expect(transposedMatrix.data).toEqual([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ]); + }); + + test('should transpose an empty matrix correctly', () => { + const originalMatrix = new Matrix([]); + + const transposedMatrix = originalMatrix.transpose(); + + expect(transposedMatrix.rows).toBe(0); + expect(transposedMatrix.cols).toBe(0); + expect(transposedMatrix.data).toEqual([]); + }); + + test('should throw an error when transposing a non-rectangular matrix', () => { + const originalMatrix = new Matrix([ + [1, 2, 3], + [4, 5] + ]); + + // Using a lambda to call transpose because Jest expects the error to be thrown within a function + expect(() => originalMatrix.transpose()).toThrowError('Matrix must be rectangular for transposition.'); + }); + }); + + describe('inverse', () => { + it('should calculate the inverse of a 2x2 matrix', () => { + const data: number[][] = [ + [1, 2], + [3, 4] + ]; + + const matrix = new Matrix(data); + const inverseMatrix = matrix.inverse(); + + const expectedInverse: number[][] = [ + [-2, 1], + [1.5, -0.5] + ]; + + expect(inverseMatrix?.data).toEqual(expectedInverse); + }); + + it('should calculate the inverse of a 3x3 matrix', () => { + const data: number[][] = [ + [4, 7, 2], + [2, 6, 3], + [1, 2, 5] + ]; + + const matrix = new Matrix(data); + const inverseMatrix = matrix.inverse(); + + // const expectedInverse: number[][] = [ + // [24 / 43, -31 / 43, 9 / 43], + // [-7 / 43, 18 / 43, -8 / 43], + // [-2 / 43, -1 / 43, 10 / 43], + // ]; + + expect(inverseMatrix?.data).toEqual([ + [0.558139534883721, -0.7209302325581396, 0.2093023255813954], + [-0.16279069767441862, 0.4186046511627907, -0.18604651162790697], + [-0.046511627906976744, -0.023255813953488372, 0.23255813953488372] + ]); + }); + }); + + describe('dot', () => { + test('should calculate the dot product of two matrices', () => { + const matrix1 = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrix2 = new Matrix([ + [5, 6], + [7, 8] + ]); + + const resultMatrix = matrix1.dot(matrix2); + + expect(resultMatrix?.data).toEqual([ + [19, 22], + [43, 50] + ]); + }); + + test('should throw an error for incompatible matrices', () => { + const matrix1 = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrix2 = new Matrix([ + [5, 6, 7], + [8, 9, 10], + [18, 19, 110] + ]); + expect(() => matrix1.dot(matrix2)).toThrowError( + 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.' + ); + }); + + it('should throw an error for incompatible matrices', () => { + const matrixA = new Matrix([ + [1, 2], + [3, 4] + ]); + const matrixB = new Matrix([ + [5, 6], + [7, 8], + [9, 10] + ]); + + expect(() => matrixA.dot(matrixB)).toThrowError( + 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.' + ); + }); }); }); diff --git a/test/unit/data-structures/matrix/matrix2d.test.ts b/test/unit/data-structures/matrix/matrix2d.test.ts deleted file mode 100644 index d86d1b8..0000000 --- a/test/unit/data-structures/matrix/matrix2d.test.ts +++ /dev/null @@ -1,345 +0,0 @@ -import { Matrix2D, Vector2D } from '../../../../src'; -import { isDebugTest } from '../../../config'; - -const isDebug = isDebugTest; -describe('Matrix2D', () => { - it('should initialize with default identity matrix', () => { - const matrix = new Matrix2D(); - const expectedMatrix = Matrix2D.identity; - - expect(matrix.m).toEqual(expectedMatrix); - }); - - it('should initialize with provided 2D array', () => { - const inputMatrix = [ - [2, 0, 0], - [0, 3, 0], - [0, 0, 1] - ]; - const matrix = new Matrix2D(inputMatrix); - - expect(matrix.m).toEqual(inputMatrix); - }); - - it('should initialize with provided Vector2D', () => { - expect(true).toBeTruthy(); - }); - - it('should add two matrices correctly', () => { - const matrix1 = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const matrix2 = new Matrix2D([ - [9, 8, 7], - [6, 5, 4], - [3, 2, 1] - ]); - const expectedMatrix = [ - [10, 10, 10], - [10, 10, 10], - [10, 10, 10] - ]; - - const result = Matrix2D.add(matrix1, matrix2); - - expect(result.m).toEqual(expectedMatrix); - }); - - it('should subtract two matrices correctly', () => { - const matrix1 = new Matrix2D([ - [9, 8, 7], - [6, 5, 4], - [3, 2, 1] - ]); - const matrix2 = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const expectedMatrix = [ - [8, 6, 4], - [2, 0, -2], - [-4, -6, -8] - ]; - - const result = Matrix2D.subtract(matrix1, matrix2); - - expect(result.m).toEqual(expectedMatrix); - }); - - it('should multiply two matrices correctly', () => { - const matrix1 = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const matrix2 = new Matrix2D([ - [9, 8, 7], - [6, 5, 4], - [3, 2, 1] - ]); - const expectedMatrix = [ - [30, 24, 18], - [84, 69, 54], - [138, 114, 90] - ]; - - const result = Matrix2D.multiply(matrix1, matrix2); - - expect(result.m).toEqual(expectedMatrix); - }); - - it('should multiply a matrix by a Vector2D correctly', () => { - expect(true).toBeTruthy(); - }); - - it('should scale a matrix by a value correctly', () => { - expect(true).toBeTruthy(); - }); - - it('should rotate a matrix by radians correctly', () => { - expect(true).toBeTruthy(); - }); - - it('should translate a matrix by a Vector2D correctly', () => { - const translationVector = new Vector2D(2, 3); - const expectedMatrix = [ - [1, 0, 2], - [0, 1, 3], - [0, 0, 1] - ]; - - const result = Matrix2D.translate(translationVector); - - expect(result.m).toEqual(expectedMatrix); - }); - - it('should create a view matrix correctly', () => { - expect(true).toBeTruthy(); - }); - - it('should multiply a matrix by a value correctly', () => { - const matrix = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const value = 2; - const expectedMatrix = [ - [2, 4, 6], - [8, 10, 12], - [14, 16, 18] - ]; - - const result = Matrix2D.multiplyByValue(matrix, value); - - expect(result.m).toEqual(expectedMatrix); - }); -}); - -describe('Vector2D', () => { - it('should create a vector with default values', () => { - const vector = new Vector2D(); - expect(vector.x).toBe(0); - expect(vector.y).toBe(0); - expect(vector.w).toBe(1); - }); - - it('should correctly calculate vector length', () => { - const vector = new Vector2D(3, 4); - expect(vector.length).toBe(5); - }); - - it('should correctly add two vectors', () => { - const vector1 = new Vector2D(2, 3); - const vector2 = new Vector2D(1, 2); - const result = Vector2D.add(vector1, vector2); - expect(result.x).toBe(3); - expect(result.y).toBe(5); - }); - - // Add more test cases for Vector2D methods -}); - -describe('Matrix2D', () => { - it('should create an identity matrix by default', () => { - const matrix = new Matrix2D(); - expect(matrix.m).toEqual(Matrix2D.identity); - }); - - it('should correctly add two matrices', () => { - const matrix1 = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const matrix2 = new Matrix2D([ - [9, 8, 7], - [6, 5, 4], - [3, 2, 1] - ]); - const result = Matrix2D.add(matrix1, matrix2); - expect(result.m).toEqual([ - [10, 10, 10], - [10, 10, 10], - [10, 10, 10] - ]); - }); - - // Add more test cases for Matrix2D methods -}); - -describe('Matrix2D', () => { - it('should create a matrix with default identity values', () => { - const matrix = new Matrix2D(); - expect(matrix.m).toEqual(Matrix2D.identity); - }); - - it('should create a matrix from a Vector2D', () => { - const vector = new Vector2D(2, 3); - const matrix = new Matrix2D(vector); - expect(matrix.m).toEqual([ - [2, 0, 0], - [3, 1, 0], - [1, 0, 1] - ]); - }); - - it('should correctly add two matrices', () => { - const matrix1 = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const matrix2 = new Matrix2D([ - [9, 8, 7], - [6, 5, 4], - [3, 2, 1] - ]); - const result = Matrix2D.add(matrix1, matrix2); - expect(result.m).toEqual([ - [10, 10, 10], - [10, 10, 10], - [10, 10, 10] - ]); - }); - - it('should correctly subtract two matrices', () => { - const matrix1 = new Matrix2D([ - [5, 4, 3], - [2, 1, 0], - [0, 1, 2] - ]); - const matrix2 = new Matrix2D([ - [4, 3, 2], - [1, 0, 1], - [2, 1, 0] - ]); - const result = Matrix2D.subtract(matrix1, matrix2); - expect(result.m).toEqual([ - [1, 1, 1], - [1, 1, -1], - [-2, 0, 2] - ]); - }); - - it('should correctly multiply two matrices', () => { - const matrix1 = new Matrix2D([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]); - const matrix2 = new Matrix2D([ - [9, 8, 7], - [6, 5, 4], - [3, 2, 1] - ]); - const result = Matrix2D.multiply(matrix1, matrix2); - expect(result.m).toEqual([ - [30, 24, 18], - [84, 69, 54], - [138, 114, 90] - ]); - }); - - it('should correctly multiply a matrix by a value', () => { - const matrix = new Matrix2D([ - [2, 3, 4], - [5, 6, 7], - [8, 9, 10] - ]); - const value = 2; - const result = Matrix2D.multiplyByValue(matrix, value); - expect(result.m).toEqual([ - [4, 6, 8], - [10, 12, 14], - [16, 18, 20] - ]); - }); - - it('should correctly multiply a matrix by a vector', () => { - const matrix = new Matrix2D([ - [2, 3, 4], - [5, 6, 7], - [8, 9, 10] - ]); - const vector = new Vector2D(2, 3); - const result = Matrix2D.multiplyByVector(matrix, vector); - isDebug && console.log(JSON.stringify(result)); - expect(result).toEqual({ x: 17, y: 35, w: 1 }); - }); - - it('should correctly create a view matrix', () => { - const width = 800; - const height = 600; - const viewMatrix = Matrix2D.view(width, height); - expect(viewMatrix.m).toEqual([ - [1, 0, 400], - [0, -1, 300], - [0, 0, 1] - ]); - }); - - it('should correctly scale a matrix', () => { - const factor = 3; - const scaledMatrix = Matrix2D.scale(factor); - expect(scaledMatrix.m).toEqual([ - [3, 0, 0], - [0, 3, 0], - [0, 0, 3] - ]); - }); - - it('should correctly rotate a matrix', () => { - const radians = Math.PI / 4; // 45 degrees - const rotationMatrix = Matrix2D.rotate(radians); - isDebug && console.log(JSON.stringify(rotationMatrix.m)); - expect(rotationMatrix.m).toEqual([ - [0.7071067811865476, -0.7071067811865475, 0], - [0.7071067811865475, 0.7071067811865476, 0], - [0, 0, 1] - ]); - }); - - it('should correctly translate a matrix', () => { - const translationVector = new Vector2D(2, 3); - const translationMatrix = Matrix2D.translate(translationVector); - expect(translationMatrix.m).toEqual([ - [1, 0, 2], - [0, 1, 3], - [0, 0, 1] - ]); - }); - - it('should correctly convert a matrix to a vector', () => { - const matrix = new Matrix2D([ - [2, 3, 4], - [5, 6, 7], - [8, 9, 10] - ]); - const vector = matrix.toVector(); - expect(vector).toEqual(new Vector2D(2, 5)); - }); -}); diff --git a/test/unit/data-structures/matrix/vector2d.test.ts b/test/unit/data-structures/matrix/vector2d.test.ts deleted file mode 100644 index aecb395..0000000 --- a/test/unit/data-structures/matrix/vector2d.test.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { Vector2D } from '../../../../src'; - -describe('Vector2D', () => { - it('should create a vector with default values', () => { - const vector = new Vector2D(); - expect(vector.x).toBe(0); - expect(vector.y).toBe(0); - expect(vector.w).toBe(1); - }); - - it('should correctly check if a vector is zero', () => { - const nonZeroVector = new Vector2D(3, 4); - const zeroVector = new Vector2D(0, 0); - expect(nonZeroVector.isZero).toBe(false); - expect(zeroVector.isZero).toBe(true); - }); - - it('should correctly calculate vector length', () => { - const vector = new Vector2D(3, 4); - expect(vector.length).toBe(5); - }); - - it('should correctly calculate squared vector length', () => { - const vector = new Vector2D(3, 4); - expect(vector.lengthSq).toBe(25); - }); - - it('should correctly round vector components', () => { - const vector = new Vector2D(3.6, 4.3); - const roundedVector = vector.rounded; - expect(roundedVector.x).toBe(4); - expect(roundedVector.y).toBe(4); - }); - - it('should correctly add two vectors', () => { - const vector1 = new Vector2D(2, 3); - const vector2 = new Vector2D(1, 2); - const result = Vector2D.add(vector1, vector2); - expect(result.x).toBe(3); - expect(result.y).toBe(5); - }); - - it('should correctly subtract two vectors', () => { - const vector1 = new Vector2D(4, 5); - const vector2 = new Vector2D(1, 2); - const result = Vector2D.subtract(vector1, vector2); - expect(result.x).toBe(3); - expect(result.y).toBe(3); - }); - - it('should correctly subtract value from a vector', () => { - const vector = new Vector2D(5, 7); - const result = Vector2D.subtractValue(vector, 3); - expect(result.x).toBe(2); - expect(result.y).toBe(4); - }); - - it('should correctly multiply a vector by a value', () => { - const vector = new Vector2D(2, 3); - const result = Vector2D.multiply(vector, 4); - expect(result.x).toBe(8); - expect(result.y).toBe(12); - }); - - it('should correctly divide a vector by a value', () => { - const vector = new Vector2D(6, 8); - const result = Vector2D.divide(vector, 2); - expect(result.x).toBe(3); - expect(result.y).toBe(4); - }); - - it('should correctly check if two vectors are equal', () => { - const vector1 = new Vector2D(3, 4); - const vector2 = new Vector2D(3, 4); - const vector3 = new Vector2D(4, 5); - expect(Vector2D.equals(vector1, vector2)).toBe(true); - expect(Vector2D.equals(vector1, vector3)).toBe(false); - }); - - it('should correctly check if two vectors are equal within a rounding factor', () => { - const vector1 = new Vector2D(3, 4); - const vector2 = new Vector2D(2.9, 3.9); - const vector3 = new Vector2D(4, 5); - expect(Vector2D.equalsRounded(vector1, vector2, 0.2)).toBe(true); - expect(Vector2D.equalsRounded(vector1, vector3, 0.2)).toBe(false); - }); - - it('should correctly normalize a vector', () => { - const vector = new Vector2D(3, 4); - const normalized = Vector2D.normalize(vector); - expect(normalized.x).toBeCloseTo(0.6); - expect(normalized.y).toBeCloseTo(0.8); - }); - - it('should correctly truncate a vector', () => { - const vector = new Vector2D(3, 4); - const truncated = Vector2D.truncate(vector, 4); - expect(truncated.length).toBeLessThanOrEqual(4); - }); - - it('should correctly get the perpendicular vector', () => { - const vector = new Vector2D(3, 4); - const perpendicular = Vector2D.perp(vector); - expect(Vector2D.dot(vector, perpendicular)).toBe(0); - }); - - it('should correctly reverse the vector', () => { - const vector = new Vector2D(3, 4); - const reversed = Vector2D.reverse(vector); - expect(reversed.x).toBe(-3); - expect(reversed.y).toBe(-4); - }); - - it('should correctly get the absolute vector', () => { - const vector = new Vector2D(-3, 4); - const absVector = Vector2D.abs(vector); - expect(absVector.x).toBe(3); - expect(absVector.y).toBe(4); - }); - - it('should correctly calculate the dot product of two vectors', () => { - const vector1 = new Vector2D(2, 3); - const vector2 = new Vector2D(4, 5); - const dotProduct = Vector2D.dot(vector1, vector2); - expect(dotProduct).toBe(23); - }); - - it('should correctly calculate the distance between two vectors', () => { - const vector1 = new Vector2D(1, 1); - const vector2 = new Vector2D(4, 5); - const distance = Vector2D.distance(vector1, vector2); - expect(distance).toBeCloseTo(5); - }); - - it('should correctly calculate the squared distance between two vectors', () => { - const vector1 = new Vector2D(1, 1); - const vector2 = new Vector2D(4, 5); - const distanceSq = Vector2D.distanceSq(vector1, vector2); - expect(distanceSq).toBe(25); - }); - - it('should correctly determine the sign of the cross product of two vectors', () => { - const vector1 = new Vector2D(2, 3); - const vector2 = new Vector2D(4, 5); - const sign = Vector2D.sign(vector1, vector2); - expect(sign).toBe(-1); // Assuming specific vector values, the result may vary - }); - - it('should correctly calculate the angle between a vector and the negative y-axis', () => { - const vector = new Vector2D(3, 4); - const angle = Vector2D.angle(vector); - expect(angle).toBeCloseTo(2.498091544796509, 3); - }); - - it('should create a random vector within the specified range', () => { - const maxX = 10; - const maxY = 10; - const randomVector = Vector2D.random(maxX, maxY); - expect(randomVector.x).toBeGreaterThanOrEqual(-maxX / 2); - expect(randomVector.x).toBeLessThanOrEqual(maxX / 2); - expect(randomVector.y).toBeGreaterThanOrEqual(-maxY / 2); - expect(randomVector.y).toBeLessThanOrEqual(maxY / 2); - }); - - it('should zero the vector components', () => { - const vector = new Vector2D(3, 4); - vector.zero(); - expect(vector.x).toBe(0); - expect(vector.y).toBe(0); - }); -}); diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..e9443cd --- /dev/null +++ b/typedoc.json @@ -0,0 +1,30 @@ +{ + "visibilityFilters": { + "protected": false, + "private": false, + "inherited": true, + "external": false, + "@alpha": false, + "@beta": false + }, + "excludeNotDocumented": true, + "excludeNotDocumentedKinds": [ + "Module", + "Namespace", + "Enum", + "Variable", + "Function", + "Interface", + "Constructor", + "Property", + "Method", + "CallSignature", + "IndexSignature", + "ConstructorSignature", + "Accessor", + "GetSignature", + "SetSignature", + "TypeAlias", + "Reference" + ] +} \ No newline at end of file