From f15251096c00682531e6318b5a5b40a917d66a41 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Tue, 3 Dec 2024 16:47:45 -0700 Subject: [PATCH 01/35] sdk beta.0 --- sdk/package/package-lock.json | 4 ++-- sdk/package/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/package/package-lock.json b/sdk/package/package-lock.json index 1f5715258..9abc963fb 100644 --- a/sdk/package/package-lock.json +++ b/sdk/package/package-lock.json @@ -1,12 +1,12 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha.21", + "version": "0.3.6-beta.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha.21", + "version": "0.3.6-beta.0", "license": "MIT", "dependencies": { "@iarna/toml": "^2.2.5", diff --git a/sdk/package/package.json b/sdk/package/package.json index 2bf4b71f5..a5bb78159 100644 --- a/sdk/package/package.json +++ b/sdk/package/package.json @@ -1,6 +1,6 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha.21", + "version": "0.3.6-beta.0", "description": "Software development kit to facilitate packaging services for StartOS", "main": "./package/lib/index.js", "types": "./package/lib/index.d.ts", From 1859c0505e1170d29b20d4b63899112cc6523177 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Fri, 6 Dec 2024 08:53:59 -0700 Subject: [PATCH 02/35] remove deprecated useHash param --- web/projects/install-wizard/src/app/app-routing.module.ts | 1 - web/projects/setup-wizard/src/app/app-routing.module.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/web/projects/install-wizard/src/app/app-routing.module.ts b/web/projects/install-wizard/src/app/app-routing.module.ts index 80901192f..ab9831822 100644 --- a/web/projects/install-wizard/src/app/app-routing.module.ts +++ b/web/projects/install-wizard/src/app/app-routing.module.ts @@ -14,7 +14,6 @@ const routes: Routes = [ RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled', preloadingStrategy: PreloadAllModules, - useHash: true, }), ], exports: [RouterModule], diff --git a/web/projects/setup-wizard/src/app/app-routing.module.ts b/web/projects/setup-wizard/src/app/app-routing.module.ts index aa56c382d..78088236a 100644 --- a/web/projects/setup-wizard/src/app/app-routing.module.ts +++ b/web/projects/setup-wizard/src/app/app-routing.module.ts @@ -47,7 +47,6 @@ const routes: Routes = [ RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled', preloadingStrategy: PreloadAllModules, - useHash: true, initialNavigation: 'disabled', }), ], From c675d0feeec8837944ae4a04e310ad1c8637f39f Mon Sep 17 00:00:00 2001 From: Mariusz Kogen Date: Tue, 10 Dec 2024 17:55:20 +0100 Subject: [PATCH 03/35] Escape backslashes in /etc/issue to prevent unwanted newlines (#2797) --- debian/postinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/postinst b/debian/postinst index 3714df8d4..bf9a8938e 100755 --- a/debian/postinst +++ b/debian/postinst @@ -26,7 +26,7 @@ if [ -f /etc/default/grub ]; then fi # set local and remote login prompt -echo "StartOS v$(cat /usr/lib/startos/VERSION.txt) [\m] on \n.local (\l)" > /etc/issue +echo "StartOS v$(cat /usr/lib/startos/VERSION.txt) [\\m] on \\n.local (\\l)" > /etc/issue echo "StartOS v$(cat /usr/lib/startos/VERSION.txt)" > /etc/issue.net # change timezone From e9d851e4d39d00416bd1d827c60eab4d6ea6498f Mon Sep 17 00:00:00 2001 From: Alex Inkin Date: Thu, 12 Dec 2024 03:14:01 +0400 Subject: [PATCH 04/35] fix: reset sideload service after websocket completes (#2798) * fix: reset sideload service after websocket completes * chore: fix comment --- web/package-lock.json | 4477 ++++++++++------- web/package.json | 3 +- .../server-routes/sideload/sideload.page.ts | 4 +- .../sideload/sideload.service.ts | 12 +- 4 files changed, 2577 insertions(+), 1919 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index a36b7511e..5652a0406 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -30,6 +30,7 @@ "@start9labs/emver": "^0.1.5", "@start9labs/start-sdk": "file:../sdk/baseDist", "@taiga-ui/addon-charts": "3.96.0", + "@taiga-ui/addon-commerce": "3.96.0", "@taiga-ui/cdk": "3.96.0", "@taiga-ui/core": "3.96.0", "@taiga-ui/experimental": "3.96.0", @@ -61,7 +62,7 @@ "pbkdf2": "^3.1.2", "rxjs": "^7.8.1", "swiper": "^8.2.4", - "ts-matches": "^5.5.1", + "ts-matches": "^6.1.0", "tslib": "^2.3.0", "uuid": "^8.3.2", "zone.js": "^0.11.5" @@ -115,72 +116,20 @@ "rxjs": ">=7.0.0" } }, - "../sdk/baseDist": { - "name": "@start9labs/start-sdk-base", - "license": "MIT", - "dependencies": { - "@iarna/toml": "^2.2.5", - "@noble/curves": "^1.4.0", - "@noble/hashes": "^1.4.0", - "isomorphic-fetch": "^3.0.0", - "lodash.merge": "^4.6.2", - "mime-types": "^2.1.35", - "ts-matches": "^5.5.1", - "yaml": "^2.2.2" - }, - "devDependencies": { - "@types/jest": "^29.4.0", - "@types/lodash.merge": "^4.6.2", - "@types/mime-types": "^2.1.4", - "jest": "^29.4.3", - "peggy": "^3.0.2", - "prettier": "^3.2.5", - "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "ts-pegjs": "^4.2.1", - "tsx": "^4.7.1", - "typescript": "^5.0.4" - } - }, - "../sdk/dist": { - "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha8", - "extraneous": true, - "license": "MIT", - "dependencies": { - "@iarna/toml": "^2.2.5", - "@noble/curves": "^1.4.0", - "@noble/hashes": "^1.4.0", - "isomorphic-fetch": "^3.0.0", - "lodash.merge": "^4.6.2", - "mime": "^4.0.3", - "ts-matches": "^5.5.1", - "yaml": "^2.2.2" - }, - "devDependencies": { - "@types/jest": "^29.4.0", - "@types/lodash.merge": "^4.6.2", - "jest": "^29.4.3", - "peggy": "^3.0.2", - "prettier": "^3.2.5", - "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "ts-pegjs": "^4.2.1", - "tsx": "^4.7.1", - "typescript": "^5.0.4" - } - }, + "../sdk/baseDist": {}, "node_modules/@adobe/css-tools": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", - "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", - "dev": true + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true, + "license": "MIT" }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -194,6 +143,7 @@ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "14.2.13", "rxjs": "6.6.7" @@ -209,6 +159,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -220,13 +171,15 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "devOptional": true + "devOptional": true, + "license": "0BSD" }, "node_modules/@angular-devkit/build-angular": { "version": "14.2.13", "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.13.tgz", "integrity": "sha512-FJZKQ3xYFvEJ807sxVy4bCVyGU2NMl3UUPNfLIdIdzwwDEP9tx/cc+c4VtVPEZZfU8jVenu8XOvL6L0vpjt3yg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "2.2.0", "@angular-devkit/architect": "0.1402.13", @@ -335,6 +288,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1" @@ -344,25 +298,29 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", @@ -373,13 +331,15 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", @@ -392,6 +352,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -401,6 +362,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } @@ -409,13 +371,15 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", @@ -432,6 +396,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", @@ -445,6 +410,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", @@ -457,6 +423,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", @@ -471,6 +438,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" @@ -481,6 +449,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -497,6 +466,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -505,19 +475,22 @@ "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -529,13 +502,15 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@angular-devkit/build-angular/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -553,13 +528,15 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@angular-devkit/build-angular/node_modules/webpack": { "version": "5.76.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -607,6 +584,7 @@ "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.13.tgz", "integrity": "sha512-K27aJmuw86ZOdiu5PoGeGDJ2v7g2ZCK0bGwc8jzkjTLRfvd4FRKIIZumGv3hbQ3vQRLikiU6WMDRTFyCZky/EA==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1402.13", "rxjs": "6.6.7" @@ -626,6 +604,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -637,12 +616,14 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@angular-devkit/core": { "version": "14.2.13", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", + "license": "MIT", "dependencies": { "ajv": "8.11.0", "ajv-formats": "2.1.1", @@ -668,6 +649,7 @@ "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -678,12 +660,14 @@ "node_modules/@angular-devkit/core/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" }, "node_modules/@angular-devkit/schematics": { "version": "14.2.13", "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.13.tgz", "integrity": "sha512-2zczyeNzeBcrT2HOysv52X9SH3tZoHfWJvVf6H0SIa74rfDKEl7hFpKNXnh3x8sIMLj5mZn05n5RCqGxCczcIg==", + "license": "MIT", "dependencies": { "@angular-devkit/core": "14.2.13", "jsonc-parser": "3.1.0", @@ -701,6 +685,7 @@ "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -711,12 +696,14 @@ "node_modules/@angular-devkit/schematics/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" }, "node_modules/@angular/animations": { "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-14.3.0.tgz", "integrity": "sha512-QoBcIKy1ZiU+4qJsAh5Ls20BupWiXiZzKb0s6L9/dntPt5Msr4Ao289XR2P6O1L+kTsCprH9Kt41zyGQ/bkRqg==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -732,6 +719,7 @@ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.13.tgz", "integrity": "sha512-I5EepRem2CCyS3GDzQxZ2ZrqQwVqoGoLY+ZQhsK1QGWUnUyFOjbv3OlUGxRUYwcedu19V1EBAKjmQ96HzMIcVQ==", "devOptional": true, + "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1402.13", "@angular-devkit/core": "14.2.13", @@ -767,6 +755,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.3.0.tgz", "integrity": "sha512-pV9oyG3JhGWeQ+TFB0Qub6a1VZWMNZ6/7zEopvYivdqa5yDLLDSBRWb6P80RuONXyGnM1pa7l5nYopX+r/23GQ==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -782,6 +771,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.3.0.tgz", "integrity": "sha512-E15Rh0t3vA+bctbKnBCaDmLvc3ix+ZBt6yFZmhZalReQ+KpOlvOJv+L9oiFEgg+rYVl2QdvN7US1fvT0PqswLw==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -802,6 +792,7 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.3.0.tgz", "integrity": "sha512-eoKpKdQ2X6axMgzcPUMZVYl3bIlTMzMeTo5V29No4BzgiUB+QoOTYGNJZkGRyqTNpwD9uSBJvmT2vG9+eC4ghQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.17.2", "chokidar": "^3.0.0", @@ -831,6 +822,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.3.0.tgz", "integrity": "sha512-wYiwItc0Uyn4FWZ/OAx/Ubp2/WrD3EgUJ476y1XI7yATGPF8n9Ld5iCXT08HOvc4eBcYlDfh90kTXR6/MfhzdQ==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -846,6 +838,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.3.0.tgz", "integrity": "sha512-fBZZC2UFMom2AZPjGQzROPXFWO6kvCsPDKctjJwClVC8PuMrkm+RRyiYRdBbt2qxWHEqOZM2OCQo73xUyZOYHw==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -864,6 +857,7 @@ "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-14.3.0.tgz", "integrity": "sha512-Sij3OQzj1UGs1O8H9PxVAY/o27+oqZwQRnib66rsWvtbIBTjHp4FV3dTs5iVcr62GGv4V4Mff/2I82NP10GPQg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || >=16.10.0" } @@ -872,6 +866,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.3.0.tgz", "integrity": "sha512-w9Y3740UmTz44T0Egvc+4QV9sEbO61L+aRHbpkLTJdlEGzHByZvxJmJyBYmdqeyTPwc/Zpy7c02frlpfAlyB7A==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -893,6 +888,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.3.0.tgz", "integrity": "sha512-rneZiMrIiYRhrkQvdL40E2ErKRn4Zdo6EtjBM9pAmWeyoM8oMnOZb9gz5vhrkNWg06kVMVg0yKqluP5How7j3A==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -910,6 +906,7 @@ "version": "14.2.13", "resolved": "https://registry.npmjs.org/@angular/pwa/-/pwa-14.2.13.tgz", "integrity": "sha512-WPkTgT3+VC/KeZMydZnTQJWTG5IVTSdkJfqmNQWfHXzpmm1CG4KvFRj3xEOXvaDmcL56nnqKhL/o66kpai15Qw==", + "license": "MIT", "dependencies": { "@angular-devkit/schematics": "14.2.13", "@schematics/angular": "14.2.13", @@ -933,6 +930,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.3.0.tgz", "integrity": "sha512-uip0V7w7k7xyxxpTPbr7EuMnYLj3FzJrwkLVJSEw3TMMGHt5VU5t4BBa9veGZOta2C205XFrTAHnp8mD+XYY1w==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -950,6 +948,7 @@ "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-14.3.0.tgz", "integrity": "sha512-i5O7m1gQijWm7cgva0XTmOVBFrPrttNxFDwoMLMYCh8rHOCQUQ4DcVO1qTBPWU4SrY5BYPEvR+r05dYQLFYCBw==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -968,15 +967,18 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -984,10 +986,11 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -997,6 +1000,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -1027,6 +1031,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1036,6 +1041,7 @@ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.18.10", "@jridgewell/gen-mapping": "^0.3.2", @@ -1050,6 +1056,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1064,6 +1071,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.18.6" }, @@ -1071,28 +1079,16 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -1105,24 +1101,24 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", - "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -1133,12 +1129,13 @@ } }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1149,18 +1146,20 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", - "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -1171,12 +1170,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1187,6 +1187,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1196,6 +1197,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", @@ -1213,6 +1215,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1222,45 +1225,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.24.7" }, @@ -1269,42 +1234,43 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", - "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1314,35 +1280,38 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", - "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-wrap-function": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1352,26 +1321,28 @@ } }, "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", - "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.7", - "@babel/helper-optimise-call-expression": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1380,147 +1351,118 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", - "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -1529,12 +1471,13 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", - "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1544,14 +1487,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1566,6 +1510,7 @@ "integrity": "sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.18.9", @@ -1585,6 +1530,7 @@ "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1602,6 +1548,7 @@ "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", @@ -1620,6 +1567,7 @@ "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -1637,6 +1585,7 @@ "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -1654,6 +1603,7 @@ "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -1671,6 +1621,7 @@ "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -1688,6 +1639,7 @@ "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1705,6 +1657,7 @@ "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -1722,6 +1675,7 @@ "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.7", @@ -1742,6 +1696,7 @@ "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -1759,6 +1714,7 @@ "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -1777,6 +1733,7 @@ "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1794,6 +1751,7 @@ "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.21.0", @@ -1813,6 +1771,7 @@ "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1829,6 +1788,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1841,6 +1801,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -1853,6 +1814,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1868,6 +1830,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1880,6 +1843,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -1888,12 +1852,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1907,6 +1872,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1919,6 +1885,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1931,6 +1898,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1943,6 +1911,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1955,6 +1924,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1967,6 +1937,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1979,6 +1950,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1991,6 +1963,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -2006,6 +1979,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -2017,12 +1991,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2036,6 +2011,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -2049,12 +2025,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2064,12 +2041,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", - "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2079,18 +2057,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", - "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -2101,25 +2078,27 @@ } }, "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2129,26 +2108,28 @@ } }, "node_modules/@babel/plugin-transform-computed-properties/node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", - "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2158,13 +2139,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2174,12 +2156,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2189,13 +2172,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2205,13 +2188,14 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2221,14 +2205,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", - "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2238,12 +2223,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", - "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2253,12 +2239,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2268,13 +2255,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2284,14 +2272,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", - "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2301,15 +2289,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", - "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2319,13 +2308,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2335,13 +2325,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2351,12 +2342,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2366,13 +2358,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2382,14 +2375,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", - "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2399,12 +2392,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2414,12 +2408,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2429,12 +2424,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -2445,12 +2441,13 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2464,6 +2461,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.10.tgz", "integrity": "sha512-q5mMeYAdfEbpBAgzl7tBre/la3LeCxmDO1+wMXRdPWbcoMjR3GiXlCLk7JBZVVye0bqTGNMbt0yYVXX1B1jEWQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.9", @@ -2484,17 +2482,19 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2504,13 +2504,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2520,12 +2521,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2535,12 +2537,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2550,12 +2553,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", - "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2565,12 +2569,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2580,13 +2585,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2600,6 +2606,7 @@ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz", "integrity": "sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.18.8", "@babel/helper-compilation-targets": "^7.18.9", @@ -2689,6 +2696,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -2698,6 +2706,7 @@ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -2709,17 +2718,12 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, "node_modules/@babel/runtime": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -2732,6 +2736,7 @@ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.18.10", @@ -2742,19 +2747,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2763,15 +2766,32 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2782,6 +2802,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2791,15 +2812,28 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "node_modules/@babel/traverse/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2810,6 +2844,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2822,6 +2857,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -2832,6 +2868,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" @@ -2847,11 +2884,43 @@ "postcss": "^8.2" } }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "license": "CC0-1.0", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@csstools/postcss-color-function": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -2872,6 +2941,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2891,6 +2961,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2910,6 +2981,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -2930,6 +3002,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -2945,11 +3018,43 @@ "postcss": "^8.2" } }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "license": "CC0-1.0", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@csstools/postcss-nested-calc": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2969,6 +3074,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2988,6 +3094,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -3008,6 +3115,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -3023,6 +3131,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -3042,6 +3151,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -3061,6 +3171,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -3080,6 +3191,7 @@ "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", "dev": true, + "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -3091,27 +3203,12 @@ "postcss": "^8.2" } }, - "node_modules/@csstools/selector-specificity": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", - "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", - "dev": true, - "engines": { - "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.10" - } - }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -3124,6 +3221,7 @@ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3136,12 +3234,14 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@ionic/angular": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.7.5.tgz", "integrity": "sha512-nV8HP7RedjYkIAT8nVr5ifHNT0D3XzA74RPG3/WCCFJKunERNJ9SBiNkCTWhUpSkqsYYwEB4+SOOHz+R5NLk/w==", + "license": "MIT", "dependencies": { "@ionic/core": "6.7.5", "ionicons": "^6.1.3", @@ -3161,6 +3261,7 @@ "resolved": "https://registry.npmjs.org/@ionic/cli/-/cli-6.20.9.tgz", "integrity": "sha512-sItLCi7zXq1zARWIpZDinHhK8hvy+wzOx176QMOJV90BjDybkjGYu3rGu5TBjoqn104dRIZTC8rtCsnD/P3cQw==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/cli-framework": "5.1.3", "@ionic/cli-framework-output": "2.2.5", @@ -3201,6 +3302,7 @@ "resolved": "https://registry.npmjs.org/@ionic/cli-framework/-/cli-framework-5.1.3.tgz", "integrity": "sha512-T2KN/TurzNoAcc3iDt1KHU6GeEa7x9kXngMnu5xs+DzJv5HhBKjVOoo74b8rgVxdPx+dLOV8aLrorlyvsHR/tQ==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/cli-framework-output": "2.2.5", "@ionic/utils-array": "2.1.5", @@ -3227,6 +3329,7 @@ "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.5.tgz", "integrity": "sha512-YeDLTnTaE6V4IDUxT8GDIep0GuRIFaR7YZDLANMuuWJZDmnTku6DP+MmQoltBeLmVvz1BAAZgk41xzxdq6H2FQ==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/utils-terminal": "2.3.3", "debug": "^4.0.0", @@ -3241,6 +3344,7 @@ "resolved": "https://registry.npmjs.org/@ionic/cli-framework-prompts/-/cli-framework-prompts-2.1.10.tgz", "integrity": "sha512-h8HbA0teR0vWtGKB3ahzRbDq4yYaxfukgbOqhu9CAEJHosoFlBmDB8PbPnGFYxUg2J1MuCqeiN2ftJQYV/BO1w==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/utils-terminal": "2.3.3", "debug": "^4.0.0", @@ -3251,69 +3355,12 @@ "node": ">=10.3.0" } }, - "node_modules/@ionic/cli-framework-prompts/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/@ionic/cli-framework-prompts/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@ionic/cli-framework-prompts/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/@ionic/cli-framework-prompts/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/@ionic/cli-framework-prompts/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@ionic/cli-framework-prompts/node_modules/inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", @@ -3338,6 +3385,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -3349,153 +3397,15 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/@ionic/cli-framework-prompts/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@ionic/cli-framework/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/@ionic/cli-framework/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@ionic/cli-framework/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/@ionic/cli-framework/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/@ionic/cli-framework/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@ionic/cli-framework/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@ionic/cli/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/@ionic/cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@ionic/cli/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/@ionic/cli/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/@ionic/cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "license": "0BSD" }, "node_modules/@ionic/cli/node_modules/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dev": true, + "license": "MIT", "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -3507,22 +3417,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ionic/cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@ionic/core": { "version": "6.7.5", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.7.5.tgz", "integrity": "sha512-zRkRn+h/Vs3xt/EVgBdShMKDyeGOM4RU31NPF2icfu3CUTH+VrMV569MUnNjYvd1Lu2xK90pYy4TaicSWmC1Pw==", + "license": "MIT", "dependencies": { "@stencil/core": "^2.18.0", "ionicons": "^6.1.3", @@ -3534,6 +3433,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -3547,6 +3447,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", "dev": true, + "license": "MIT", "dependencies": { "@types/fs-extra": "^8.0.0", "debug": "^4.0.0", @@ -3562,6 +3463,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-network/-/utils-network-2.1.5.tgz", "integrity": "sha512-HUQ1Ec4Mh2MXzzKdbbbDS6xYKwpFJ2XRY7SYXbaZT8+jiNahfHbsOfe62/p8bk41Yil7E9EagzGC2JvIFJh01w==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -3575,6 +3477,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -3588,6 +3491,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/utils-object": "2.1.5", "@ionic/utils-terminal": "2.3.3", @@ -3605,6 +3509,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -3618,6 +3523,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/utils-array": "2.1.5", "@ionic/utils-fs": "3.1.6", @@ -3637,6 +3543,7 @@ "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/slice-ansi": "^4.0.0", "debug": "^4.0.0", @@ -3657,6 +3564,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -3673,6 +3581,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -3682,6 +3591,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -3694,13 +3604,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3710,6 +3622,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3723,6 +3636,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -3732,6 +3646,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -3741,6 +3656,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" @@ -3751,6 +3667,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3772,6 +3689,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -3781,7 +3699,8 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@maskito/angular": { "version": "1.9.0", @@ -3824,6 +3743,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/@materia-ui/ngx-monaco-editor/-/ngx-monaco-editor-6.0.0.tgz", "integrity": "sha512-gTqNQjOGznZxOC0NlmKdKSGCJuTts8YmK4dsTQAGc5IgIV7cZdQWiW6AL742h0ruED6q0cAunEYjXT6jzHBoIQ==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -3890,6 +3810,7 @@ "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.13.tgz", "integrity": "sha512-RQx/rGX7K/+R55x1R6Ax1JzyeHi8cW11dEXpzHWipyuSpusQLUN53F02eMB4VTakXsL3mFNWWy4bX3/LSq8/9w==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || >=16.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", @@ -3902,22 +3823,39 @@ } }, "node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz", + "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==", + "license": "MIT", "dependencies": { - "@noble/hashes": "1.4.0" + "@noble/hashes": "1.6.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz", + "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", + "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", + "license": "MIT", "engines": { - "node": ">= 16" + "node": "^14.21.3 || >=16" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -3928,6 +3866,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "devOptional": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -3941,6 +3880,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3950,6 +3890,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "devOptional": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -3963,6 +3904,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", "devOptional": true, + "license": "ISC", "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" @@ -3976,6 +3918,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.2.tgz", "integrity": "sha512-CAcd08y3DWBJqJDpfuVL0uijlq5oaXaOJEKHKc4wqrjd00gkvTZB+nFuLn+doOOKddaQS9JfqtNoFCO2LCvA3w==", "devOptional": true, + "license": "ISC", "dependencies": { "@npmcli/promise-spawn": "^3.0.0", "lru-cache": "^7.4.4", @@ -3996,6 +3939,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -4005,6 +3949,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", "devOptional": true, + "license": "ISC", "dependencies": { "npm-bundled": "^1.1.1", "npm-normalize-package-bin": "^1.0.1" @@ -4022,6 +3967,7 @@ "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", "deprecated": "This functionality has been moved to @npmcli/fs", "devOptional": true, + "license": "MIT", "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -4035,6 +3981,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz", "integrity": "sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A==", "devOptional": true, + "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } @@ -4044,6 +3991,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz", "integrity": "sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g==", "devOptional": true, + "license": "ISC", "dependencies": { "infer-owner": "^1.0.4" }, @@ -4056,6 +4004,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-4.2.1.tgz", "integrity": "sha512-7dqywvVudPSrRCW5nTHpHgeWnbBtz8cFkOuKrecm6ih+oO9ciydhWt6OF7HlqupRRmB8Q/gECVdB9LMfToJbRg==", "devOptional": true, + "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^2.0.0", "@npmcli/promise-spawn": "^3.0.0", @@ -4068,16 +4017,18 @@ } }, "node_modules/@polka/url": { - "version": "1.0.0-next.25", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", - "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", - "dev": true + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" }, "node_modules/@rollup/plugin-json": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.0.8" }, @@ -4090,6 +4041,7 @@ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.1.0", "@types/resolve": "1.17.1", @@ -4110,6 +4062,7 @@ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", @@ -4126,12 +4079,14 @@ "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@schematics/angular": { "version": "14.2.13", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.13.tgz", "integrity": "sha512-MLxTpTU3E8QACQ/5c0sENMR2gRiMXpGaKeD5IHY+3wyU2fUSJVB0QPU/l1WhoyZbX8N9ospBgf5UEG7taVF9rg==", + "license": "MIT", "dependencies": { "@angular-devkit/core": "14.2.13", "@angular-devkit/schematics": "14.2.13", @@ -4151,7 +4106,8 @@ "node_modules/@start9labs/emver": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/@start9labs/emver/-/emver-0.1.5.tgz", - "integrity": "sha512-1dhiG03VkfEwSLx/JPKVms6srAbYFQgwfSGhwpUKMDliMXuAHGVaueStmqzVxn3JpH/HEVz0QW8w/PXHqjdiIg==" + "integrity": "sha512-1dhiG03VkfEwSLx/JPKVms6srAbYFQgwfSGhwpUKMDliMXuAHGVaueStmqzVxn3JpH/HEVz0QW8w/PXHqjdiIg==", + "license": "MIT" }, "node_modules/@start9labs/start-sdk": { "resolved": "../sdk/baseDist", @@ -4161,6 +4117,7 @@ "version": "2.22.3", "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.22.3.tgz", "integrity": "sha512-kmVA0M/HojwsfkeHsifvHVIYe4l5tin7J5+DLgtl8h6WWfiMClND5K3ifCXXI2ETDNKiEk21p6jql3Fx9o2rng==", + "license": "MIT", "bin": { "stencil": "bin/stencil" }, @@ -4191,7 +4148,6 @@ "resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.96.0.tgz", "integrity": "sha512-Y1MACB6KrQVnNjgeKQrNfbz51jMXbU7j83sL28+6q8DS9LNv4DVcv/r/UvK2VZ1PhESkBU85NJAIHf5iy9GN4g==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": ">=2.7.0" }, @@ -4237,9 +4193,9 @@ } }, "node_modules/@taiga-ui/cdk/node_modules/@angular-devkit/core": { - "version": "18.2.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.9.tgz", - "integrity": "sha512-bsVt//5E0ua7FZfO0dCF/qGGY6KQD34/bNGyRu5B6HedimpdU2/0PGDptksU5v3yKEc9gNw0xC6mT0UsY/R9pA==", + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.4.tgz", + "integrity": "sha512-+imxIj1JLr2hbUYQePHgkTUKr0VmlxNSZvIREcCWtXUcdCypiwhJAtGXv6MfpB4hAx+FJZYEpVWeLwYOS/gW0A==", "license": "MIT", "optional": true, "peer": true, @@ -4257,7 +4213,7 @@ "yarn": ">= 1.13.0" }, "peerDependencies": { - "chokidar": "^3.5.2" + "chokidar": "^4.0.0" }, "peerDependenciesMeta": { "chokidar": { @@ -4266,16 +4222,16 @@ } }, "node_modules/@taiga-ui/cdk/node_modules/@angular-devkit/schematics": { - "version": "18.2.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.9.tgz", - "integrity": "sha512-aIY5/IomDOINGCtFYi77uo0acDpdQNNCighfBBUGEBNMQ1eE3oGNGpLAH/qWeuxJndgmxrdKsvws9DdT46kLig==", + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.4.tgz", + "integrity": "sha512-2r6Qs4N5NSPho+qzegCYS8kIgylXyH4DHaS7HJ5+4XvM1I8V8AII8payLWkUK0i29XufVoD5XfPUFnjxZrBfYQ==", "license": "MIT", "optional": true, "peer": true, "dependencies": { - "@angular-devkit/core": "18.2.9", + "@angular-devkit/core": "19.0.4", "jsonc-parser": "3.3.1", - "magic-string": "0.30.11", + "magic-string": "0.30.12", "ora": "5.4.1", "rxjs": "7.8.1" }, @@ -4322,6 +4278,23 @@ } } }, + "node_modules/@taiga-ui/cdk/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@taiga-ui/cdk/node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", @@ -4330,9 +4303,9 @@ "optional": true }, "node_modules/@taiga-ui/cdk/node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "license": "MIT", "optional": true, "peer": true, @@ -4388,6 +4361,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@taiga-ui/cdk/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@taiga-ui/core": { "version": "3.96.0", "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.96.0.tgz", @@ -4433,9 +4421,9 @@ } }, "node_modules/@taiga-ui/i18n": { - "version": "3.96.0", - "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.96.0.tgz", - "integrity": "sha512-SGO89mRhmdD3BldQJiSqDCftEjjaOKXLJFFEZWBtrhelxKX5hWJ2lL0O+WzVAMegbQqHoT60HoHrWZIlSy9tVQ==", + "version": "3.99.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.99.0.tgz", + "integrity": "sha512-2ZfdNXVIej+DZ4t7sZ1O87+FOOkZLFYFnoxqSZy+hOMPSqqXc5EvQza/mtQFzaOAOLk9Jd8nKJQQzmHQJbuDcw==", "license": "Apache-2.0", "dependencies": { "tslib": ">=2.7.0" @@ -4490,6 +4478,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@tinkoff/ng-dompurify/-/ng-dompurify-4.0.0.tgz", "integrity": "sha512-BjKUweWLrOx8UOZw+Tl+Dae5keYuSbeMkppcXQdsvwASMrPfmP7d3Q206Q6HDqOV2WnpnFqGUB95IMbLAeRRuw==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.0.0" }, @@ -4504,6 +4493,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@tinkoff/ng-event-plugins/-/ng-event-plugins-3.2.0.tgz", "integrity": "sha512-n56R5xNfiytabh2WmWdQXfNU6m7dfOo3LLxlARE+DX7f5yciW2xBdDkuEHX74q8dlCuAVlW9aslSfz8c//ymwA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.2.0" }, @@ -4517,6 +4507,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/@tinkoff/ng-polymorpheus/-/ng-polymorpheus-4.3.0.tgz", "integrity": "sha512-Ck/XCLuBwlUgvK22PxTlLTZhGG6I32kLqLYtDQh8N/QZZhs40+hb/78/ElFGzD567CCvrzNnueFkaOoXhuEVrw==", + "license": "Apache-2.0", "dependencies": { "tslib": "2.6.2" }, @@ -4528,13 +4519,15 @@ "node_modules/@tinkoff/ng-polymorpheus/node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -4588,31 +4581,36 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -4623,6 +4621,7 @@ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4632,6 +4631,7 @@ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4641,6 +4641,7 @@ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, + "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -4650,15 +4651,17 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.4.0.tgz", "integrity": "sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==", + "license": "MIT", "dependencies": { "@types/trusted-types": "*" } }, "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -4669,6 +4672,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -4678,13 +4682,15 @@ "version": "0.0.51", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -4693,10 +4699,24 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", - "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -4709,6 +4729,7 @@ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4717,13 +4738,15 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4732,25 +4755,29 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/marked": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.2.tgz", "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/minimatch": { "version": "3.0.5", @@ -4763,19 +4790,22 @@ "version": "4.2.5", "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.2.5.tgz", "integrity": "sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "16.18.101", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz", - "integrity": "sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==", - "dev": true + "version": "16.18.121", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.121.tgz", + "integrity": "sha512-Gk/pOy8H0cvX8qNrwzElYIECpcUn87w4EAEFXFvPJ8qsP9QR/YqukUORSy0zmyDyvdo149idPpy4W6iC5aSbQA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node-forge": { "version": "1.3.11", "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4785,6 +4815,7 @@ "resolved": "https://registry.npmjs.org/@types/node-jose/-/node-jose-1.1.13.tgz", "integrity": "sha512-QjMd4yhwy1EvSToQn0YI3cD29YhyfxFwj7NecuymjLys2/P0FwxWnkgBlFxCai6Y3aBCe7rbwmqwJJawxlgcXw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4793,34 +4824,39 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4829,13 +4865,15 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -4846,6 +4884,7 @@ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dev": true, + "license": "MIT", "dependencies": { "@types/express": "*" } @@ -4855,6 +4894,7 @@ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -4865,13 +4905,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/sockjs": { "version": "0.3.36", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4879,181 +4921,199 @@ "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -5061,38 +5121,44 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "devOptional": true + "devOptional": true, + "license": "BSD-2-Clause" }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -5101,11 +5167,22 @@ "node": ">= 0.6" } }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5117,26 +5194,19 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "deprecated": "package has been renamed to acorn-import-attributes", "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "dev": true, - "peer": true, + "license": "MIT", "peerDependencies": { "acorn": "^8" } }, "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, @@ -5149,6 +5219,7 @@ "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "dev": true, + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" @@ -5162,6 +5233,7 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -5176,6 +5248,7 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "devOptional": true, + "license": "MIT", "dependencies": { "debug": "4" }, @@ -5188,6 +5261,7 @@ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", "devOptional": true, + "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" }, @@ -5200,6 +5274,7 @@ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "devOptional": true, + "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -5212,6 +5287,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -5227,6 +5303,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -5244,6 +5321,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -5255,6 +5333,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/angular-svg-round-progressbar/-/angular-svg-round-progressbar-9.0.0.tgz", "integrity": "sha512-q8d2AEG9u+GMAMrZY40NgejN5fHwR4iK+rRxtJ7NnMEvvuAMqt9UEtKe0SqVQHvZYE6W16L5J9yaO+TEtfRjpw==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -5268,6 +5347,7 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5277,6 +5357,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "devOptional": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -5295,6 +5376,7 @@ "engines": [ "node >= 0.8.0" ], + "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } @@ -5303,26 +5385,31 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/ansi-to-html": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.7.2.tgz", "integrity": "sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g==", + "license": "MIT", "dependencies": { "entities": "^2.2.0" }, @@ -5338,6 +5425,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "devOptional": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -5350,7 +5438,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/are-we-there-yet": { "version": "3.0.1", @@ -5358,6 +5447,7 @@ "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", "deprecated": "This package is no longer supported.", "devOptional": true, + "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -5370,12 +5460,14 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/array-differ": { "version": "3.0.0", @@ -5391,7 +5483,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", @@ -5418,6 +5511,7 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -5430,6 +5524,7 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5438,13 +5533,15 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 4.0.0" } @@ -5454,6 +5551,7 @@ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true, + "license": "(MIT OR Apache-2.0)", "bin": { "atob": "bin/atob.js" }, @@ -5462,9 +5560,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "dev": true, "funding": [ { @@ -5480,12 +5578,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -5503,6 +5602,7 @@ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", "dev": true, + "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.1", "loader-utils": "^2.0.0", @@ -5522,6 +5622,7 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -5536,6 +5637,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -5552,6 +5654,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", @@ -5566,6 +5669,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -5575,6 +5679,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz", "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.2", "core-js-compat": "^3.21.0" @@ -5588,6 +5693,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3" }, @@ -5599,7 +5705,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -5618,12 +5725,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/base64url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -5632,13 +5741,15 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -5648,6 +5759,7 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -5659,6 +5771,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -5683,16 +5796,18 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -5702,7 +5817,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -5717,6 +5832,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -5725,15 +5841,17 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -5743,10 +5861,11 @@ } }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -5756,13 +5875,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true + "dev": true, + "license": "ISC" }, "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==", "devOptional": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -5772,6 +5893,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "devOptional": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -5780,9 +5902,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -5798,11 +5920,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -5829,6 +5952,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -5838,13 +5962,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -5857,6 +5983,7 @@ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", "devOptional": true, + "license": "MIT", "dependencies": { "semver": "^7.0.0" } @@ -5866,6 +5993,7 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -5875,6 +6003,7 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.2.tgz", "integrity": "sha512-Xx+xPlfCZIUHagysjjOAje9nRo8pRDczQCcXb4J2O0BLtH+xeVue6ba4y1kfJfQMAnM2mkcoMIAyOctlaRGWYA==", "devOptional": true, + "license": "ISC", "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", @@ -5904,21 +6033,22 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -5927,11 +6057,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.0.tgz", + "integrity": "sha512-CCKAP2tkPau7D3GE8+V8R6sQubA9R5foIzGp+85EXCVSCivuxBNAWqcpn72PKYiIcqoViv/kcUDpaEIMBVi1lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5940,14 +6085,15 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", - "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", "dev": true, "funding": [ { @@ -5962,47 +6108,54 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/cbor": { "name": "@jprochazk/cbor", "version": "0.4.9", "resolved": "https://registry.npmjs.org/@jprochazk/cbor/-/cbor-0.4.9.tgz", - "integrity": "sha512-FWNnkOtWrFOLXKG2nzOHR/EnCCGZZPvatAvWXDmkTDxgjj9JHDK3DkMUHcFCY3a9weylMCSO/nLOUM170NAO0Q==" + "integrity": "sha512-FWNnkOtWrFOLXKG2nzOHR/EnCCGZZPvatAvWXDmkTDxgjj9JHDK3DkMUHcFCY3a9weylMCSO/nLOUM170NAO0Q==", + "license": "MIT" }, "node_modules/cbor-web": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor-web/-/cbor-web-8.1.0.tgz", "integrity": "sha512-2hWHHMVrfffgoEmsAUh8vCxHoLa1vgodtC73+C5cSarkJlwTapnqAzcHINlP6Ej0DXuP4OmmJ9LF+JaNM5Lj/g==", + "license": "MIT", "engines": { "node": ">=12.19" } }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "devOptional": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -6027,6 +6180,7 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -6036,6 +6190,7 @@ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } @@ -6044,15 +6199,20 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" } }, "node_modules/clean-stack": { @@ -6060,6 +6220,7 @@ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6068,6 +6229,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -6079,6 +6241,7 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -6091,6 +6254,7 @@ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^5.0.0" @@ -6103,10 +6267,11 @@ } }, "node_modules/cli-truncate/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==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6119,6 +6284,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6130,13 +6296,15 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6149,6 +6317,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -6165,6 +6334,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -6182,6 +6352,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -6197,6 +6368,7 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "devOptional": true, + "license": "ISC", "engines": { "node": ">= 10" } @@ -6206,6 +6378,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "devOptional": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -6216,6 +6389,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -6225,6 +6399,7 @@ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -6242,25 +6417,29 @@ "optional": true }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "devOptional": true, + "license": "ISC", "bin": { "color-support": "bin.js" } @@ -6269,13 +6448,15 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -6288,6 +6469,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || >=14" } @@ -6296,19 +6478,22 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -6318,6 +6503,7 @@ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -6326,37 +6512,30 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "dev": true, + "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6365,25 +6544,22 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -6392,13 +6568,15 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -6411,6 +6589,7 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6419,13 +6598,15 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6434,19 +6615,22 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/copy-anything": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "dev": true, + "license": "MIT", "dependencies": { "is-what": "^3.14.1" }, @@ -6459,6 +6643,7 @@ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", "dev": true, + "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", "glob-parent": "^6.0.1", @@ -6483,6 +6668,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -6495,6 +6681,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -6510,22 +6697,24 @@ } }, "node_modules/core-js": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", - "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.23.0" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -6536,13 +6725,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -6558,6 +6749,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "license": "MIT", "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -6570,6 +6762,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "license": "MIT", "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -6583,13 +6776,15 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/critters": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", "integrity": "sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.0", "css-select": "^4.2.0", @@ -6599,81 +6794,12 @@ "pretty-bytes": "^5.3.0" } }, - "node_modules/critters/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/critters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/critters/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/critters/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/critters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/critters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6688,6 +6814,7 @@ "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -6701,11 +6828,26 @@ "postcss": "^8.4" } }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/css-has-pseudo": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -6719,11 +6861,26 @@ "postcss": "^8.4" } }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/css-loader": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.7", @@ -6750,6 +6907,7 @@ "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", "dev": true, + "license": "CC0-1.0", "bin": { "css-prefers-color-scheme": "dist/cli.cjs" }, @@ -6765,6 +6923,7 @@ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -6781,6 +6940,7 @@ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -6802,13 +6962,15 @@ "type": "github", "url": "https://github.com/sponsors/csstools" } - ] + ], + "license": "CC0-1.0" }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -6820,13 +6982,15 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/data-uri-to-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -6835,13 +6999,15 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "devOptional": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -6858,6 +7024,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6867,6 +7034,7 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } @@ -6875,13 +7043,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6891,6 +7061,7 @@ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -6902,6 +7073,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -6914,6 +7086,7 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -6931,6 +7104,7 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6940,6 +7114,7 @@ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.4.tgz", "integrity": "sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw==", "dev": true, + "license": "MIT", "dependencies": { "ast-types": "^0.13.2", "escodegen": "^1.8.1", @@ -6955,6 +7130,7 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -6963,13 +7139,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6979,6 +7157,7 @@ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -6988,6 +7167,7 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -6997,13 +7177,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -7011,13 +7193,15 @@ "node_modules/dijkstrajs": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", - "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", + "license": "MIT" }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -7030,6 +7214,7 @@ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -7042,6 +7227,7 @@ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -7055,6 +7241,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/dom7/-/dom7-4.0.6.tgz", "integrity": "sha512-emjdpPLhpNubapLFdjNL9tP06Sr+GZkrIHEXLWvOGsytACUrkbeIdjO5g77m00BrHTznnlcNqgmn7pCN192TBA==", + "license": "MIT", "dependencies": { "ssr-window": "^4.0.0" } @@ -7069,13 +7256,15 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -7087,15 +7276,17 @@ } }, "node_modules/dompurify": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.5.tgz", - "integrity": "sha512-FgbqnEPiv5Vdtwt6Mxl7XSylttCC03cqP5ldNT2z+Kj0nLxPHJH4+1Cyf5Jasxhw93Rl4Oo11qRoUV72fmya2Q==" + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.7.tgz", + "integrity": "sha512-2q4bEI+coQM8f5ez7kt2xclg1XsecaV9ASJk/54vwlfRRNQfDqJz2pzQ8t0Ix/ToBpXlVjrRIx7pFC/o8itG2Q==", + "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -7105,17 +7296,34 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "readable-stream": "^2.0.2" } @@ -7125,6 +7333,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7139,13 +7348,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/duplexer2/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -7154,25 +7365,29 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.816", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", - "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==", - "dev": true + "version": "1.5.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", + "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", + "dev": true, + "license": "ISC" }, "node_modules/elementtree": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "sax": "1.1.4" }, @@ -7183,27 +7398,25 @@ "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, - "node_modules/encode-utf8": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" - }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7213,6 +7426,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -7223,6 +7437,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -7236,15 +7451,17 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -7257,6 +7474,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -7266,6 +7484,7 @@ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7274,13 +7493,15 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "prr": "~1.0.1" @@ -7294,18 +7515,17 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7315,6 +7535,7 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -7324,12 +7545,14 @@ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" }, "node_modules/esbuild": { "version": "0.15.5", @@ -7337,6 +7560,7 @@ "integrity": "sha512-VSf6S1QVqvxfIsSKb3UKr3VhUCis7wgDbtF4Vd9z84UJr05/Sp2fRKmzC+CSPG/dNAPPJZ0BTBLTT1Fhd6N9Gg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "bin": { "esbuild": "bin/esbuild" @@ -7376,6 +7600,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -7392,6 +7617,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -7408,6 +7634,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -7424,6 +7651,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -7440,6 +7668,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -7456,6 +7685,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -7472,6 +7702,7 @@ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7488,6 +7719,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7504,6 +7736,7 @@ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7520,6 +7753,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7536,6 +7770,7 @@ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7552,6 +7787,7 @@ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7568,6 +7804,7 @@ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7584,6 +7821,7 @@ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -7600,6 +7838,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -7616,6 +7855,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -7632,6 +7872,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -7645,6 +7886,7 @@ "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.15.5.tgz", "integrity": "sha512-lTJOEKekN/4JI/eOEq0wLcx53co2N6vaT/XjBz46D1tvIVoUEyM0o2K6txW6gEotf31szFD/J1PbxmnbkGlK9A==", "dev": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -7660,6 +7902,7 @@ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -7676,6 +7919,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -7692,6 +7936,7 @@ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -7701,10 +7946,11 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7713,13 +7959,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -7729,6 +7977,7 @@ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^4.2.0", @@ -7751,6 +8000,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -7761,6 +8011,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -7774,6 +8025,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -7787,6 +8039,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -7799,6 +8052,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -7808,6 +8062,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -7816,13 +8071,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -7832,6 +8089,7 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7840,19 +8098,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -7862,6 +8123,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -7884,40 +8146,42 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", - "devOptional": true + "devOptional": true, + "license": "Apache-2.0" }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -7926,6 +8190,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/debug": { @@ -7933,6 +8201,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -7941,15 +8210,17 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -7963,6 +8234,7 @@ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "devOptional": true, + "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -7975,13 +8247,15 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "devOptional": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -7996,25 +8270,29 @@ "node_modules/fast-json-patch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-uri": { "version": "3.0.3", @@ -8029,6 +8307,7 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "devOptional": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -8038,6 +8317,7 @@ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -8050,6 +8330,7 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "devOptional": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -8065,6 +8346,7 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -8074,6 +8356,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -8082,13 +8365,14 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -8104,6 +8388,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -8112,13 +8397,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -8135,6 +8422,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -8148,6 +8436,7 @@ "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", "dev": true, + "license": "MIT", "dependencies": { "semver-regex": "^3.1.2" }, @@ -8159,9 +8448,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, "funding": [ { @@ -8169,6 +8458,7 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -8179,10 +8469,11 @@ } }, "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz", + "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==", "dev": true, + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8198,6 +8489,7 @@ "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", "dev": true, + "license": "MIT", "funding": { "url": "https://ko-fi.com/tunnckoCore/commissions" } @@ -8207,6 +8499,7 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8216,6 +8509,7 @@ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, @@ -8229,6 +8523,7 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8238,6 +8533,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -8253,6 +8549,7 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "devOptional": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -8264,13 +8561,15 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "dev": true + "dev": true, + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -8278,6 +8577,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -8303,13 +8603,15 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ftp/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -8321,13 +8623,15 @@ "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "devOptional": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8336,6 +8640,7 @@ "version": "6.6.2", "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==", + "license": "Apache-2.0", "engines": { "node": ">=10" } @@ -8346,6 +8651,7 @@ "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "deprecated": "This package is no longer supported.", "devOptional": true, + "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -8365,6 +8671,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -8373,21 +8680,26 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -8401,6 +8713,7 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -8410,6 +8723,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -8422,6 +8736,7 @@ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/once": "1", "data-uri-to-buffer": "3", @@ -8439,6 +8754,7 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -8448,6 +8764,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -8462,6 +8779,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -8471,6 +8789,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -8481,6 +8800,7 @@ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", "deprecated": "Glob versions prior to v9 are no longer supported", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8500,6 +8820,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "devOptional": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -8511,13 +8832,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -8527,6 +8850,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, + "license": "MIT", "dependencies": { "dir-glob": "^3.0.1", "fast-glob": "^3.3.0", @@ -8542,12 +8866,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8557,13 +8882,15 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dev": true, + "license": "MIT", "dependencies": { "duplexer": "^0.1.2" }, @@ -8578,15 +8905,16 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { @@ -8594,6 +8922,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -8601,23 +8930,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8629,12 +8947,14 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -8649,6 +8969,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "devOptional": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -8661,6 +8982,7 @@ "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", "dev": true, + "license": "BSD", "dependencies": { "@assemblyscript/loader": "^0.10.1", "base64-js": "^1.2.0", @@ -8671,19 +8993,22 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "dev": true, + "license": "(MIT AND Zlib)" }, "node_modules/hdr-histogram-percentiles-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, + "license": "MIT", "bin": { "he": "bin/he" } @@ -8693,6 +9018,7 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "devOptional": true, + "license": "ISC", "dependencies": { "lru-cache": "^7.5.1" }, @@ -8705,6 +9031,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -8714,6 +9041,7 @@ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -8726,6 +9054,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8740,13 +9069,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -8765,31 +9096,36 @@ "type": "patreon", "url": "https://patreon.com/mdevils" } - ] + ], + "license": "MIT" }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "devOptional": true + "devOptional": true, + "license": "BSD-2-Clause" }, "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -8805,13 +9141,15 @@ "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, + "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -8826,6 +9164,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "devOptional": true, + "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -8836,10 +9175,11 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -8864,6 +9204,7 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "devOptional": true, + "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -8877,6 +9218,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -8886,6 +9228,7 @@ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "devOptional": true, + "license": "MIT", "dependencies": { "ms": "^2.0.0" } @@ -8896,6 +9239,7 @@ "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "ci-info": "^2.0.0", @@ -8920,60 +9264,12 @@ "url": "https://opencollective.com/husky" } }, - "node_modules/husky/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/husky/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/husky/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/husky/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/husky/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -8985,20 +9281,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/husky/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/husky/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -9014,6 +9302,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -9029,6 +9318,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -9044,6 +9334,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^5.0.0" }, @@ -9056,18 +9347,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/husky/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "license": "MIT", "engines": { "node": ">=8" } @@ -9077,6 +9357,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "devOptional": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -9089,6 +9370,7 @@ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -9113,13 +9395,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -9129,6 +9413,7 @@ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz", "integrity": "sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==", "devOptional": true, + "license": "ISC", "dependencies": { "minimatch": "^5.0.1" }, @@ -9141,6 +9426,7 @@ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "dev": true, + "license": "MIT", "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -9150,16 +9436,18 @@ } }, "node_modules/immutable": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", - "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", - "dev": true + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true, + "license": "MIT" }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -9176,6 +9464,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -9185,6 +9474,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -9194,6 +9484,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9202,7 +9493,8 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/inflight": { "version": "1.0.6", @@ -9210,6 +9502,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "devOptional": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -9218,13 +9511,15 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", "devOptional": true, + "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } @@ -9234,6 +9529,7 @@ "resolved": "https://registry.npmjs.org/injection-js/-/injection-js-2.4.0.tgz", "integrity": "sha512-6jiJt0tCAo9zjHbcwLiPL+IuNe9SQ6a9g0PEzafThW3fOQi0mrmiJGBJvDD6tmhPh8cQHIQtCOrJuBfQME4kPA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.0.0" } @@ -9243,6 +9539,7 @@ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -9264,80 +9561,11 @@ "node": ">=12.0.0" } }, - "node_modules/inquirer/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==", - "devOptional": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "devOptional": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/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==", - "devOptional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/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==", - "devOptional": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "devOptional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "devOptional": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ionicons": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", + "license": "MIT", "dependencies": { "@stencil/core": "^2.18.0" } @@ -9346,13 +9574,15 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "devOptional": true, + "license": "MIT", "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -9366,6 +9596,7 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -9374,13 +9605,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "devOptional": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -9393,6 +9626,7 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, + "license": "MIT", "dependencies": { "builtin-modules": "^3.3.0" }, @@ -9404,10 +9638,11 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "devOptional": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -9423,6 +9658,7 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "devOptional": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -9438,6 +9674,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9446,6 +9683,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -9455,6 +9693,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "devOptional": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -9466,6 +9705,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", "engines": { "node": ">=8" } @@ -9474,19 +9714,22 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -9496,6 +9739,7 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -9508,6 +9752,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -9520,6 +9765,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -9531,12 +9777,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -9548,13 +9796,15 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "devOptional": true, + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -9566,19 +9816,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9588,6 +9841,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -9597,6 +9851,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -9613,6 +9868,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -9622,6 +9878,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -9631,20 +9888,12 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9659,6 +9908,7 @@ "version": "4.15.9", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -9667,12 +9917,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -9684,13 +9936,15 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -9702,18 +9956,21 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -9724,13 +9981,15 @@ "node_modules/jsonc-parser": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", - "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==" + "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==", + "license": "MIT" }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -9745,13 +10004,15 @@ "devOptional": true, "engines": [ "node >= 0.2.0" - ] + ], + "license": "MIT" }, "node_modules/karma-source-map-support": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", "dev": true, + "license": "MIT", "dependencies": { "source-map-support": "^0.5.5" } @@ -9761,6 +10022,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9770,6 +10032,7 @@ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -9779,6 +10042,7 @@ "resolved": "https://registry.npmjs.org/leek/-/leek-0.0.24.tgz", "integrity": "sha512-6PVFIYXxlYF0o6hrAsHtGpTmi06otkwNrMcmQ0K96SeSRHPREPa9J3nJZ1frliVH7XT0XFswoJFQoXsDukzGNQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^2.1.0", "lodash.assign": "^3.2.0", @@ -9790,6 +10054,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -9798,13 +10063,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -9831,6 +10098,7 @@ "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.0.0.tgz", "integrity": "sha512-9+LOWWjuoectIEx3zrfN83NAGxSUB5pWEabbbidVQVgZhN+wN68pOvuyirVlH1IK4VT1f3TmlyvAnCXh8O5KEw==", "dev": true, + "license": "MIT", "dependencies": { "klona": "^2.0.4" }, @@ -9851,6 +10119,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "pify": "^4.0.1", @@ -9865,6 +10134,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "optional": true, "bin": { "mime": "cli.js" @@ -9878,6 +10148,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=6" @@ -9888,6 +10159,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver" @@ -9898,6 +10170,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -9908,6 +10181,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -9921,6 +10195,7 @@ "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", "dev": true, + "license": "ISC", "dependencies": { "webpack-sources": "^3.0.0" }, @@ -9938,6 +10213,7 @@ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -9946,13 +10222,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lint-staged": { "version": "12.5.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.5.0.tgz", "integrity": "sha512-BKLUjWDsKquV/JuIcoQW4MSAI3ggwEImF1+sB4zaKvyVx1wBk3FsG7UK9bpnmBTN1pm7EH2BBcMwINJzCRv12g==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^3.1.0", "colorette": "^2.0.16", @@ -9984,6 +10262,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -9996,6 +10275,7 @@ "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -10018,26 +10298,12 @@ } } }, - "node_modules/listr2/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/listr2/node_modules/cli-truncate": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -10049,29 +10315,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/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/listr2/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/listr2/node_modules/slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -10086,6 +10335,7 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" } @@ -10095,6 +10345,7 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12.13.0" } @@ -10103,6 +10354,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -10113,13 +10365,15 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/lodash._baseassign": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", "integrity": "sha512-t3N26QR2IdSN+gqSy9Ds9pBu/J1EAFEshKlUHpJG3rvyJOYgcELIxcIeKKfZk7sjOz11cFfzJRsyFry/JyabJQ==", "dev": true, + "license": "MIT", "dependencies": { "lodash._basecopy": "^3.0.0", "lodash.keys": "^3.0.0" @@ -10129,19 +10383,22 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash._bindcallback": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash._createassigner": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", "integrity": "sha512-LziVL7IDnJjQeeV95Wvhw6G28Z8Q6da87LWKOPWmzBLv4u6FAT/x5v00pyGW0u38UoogNF2JnD3bGgZZDaNEBw==", "dev": true, + "license": "MIT", "dependencies": { "lodash._bindcallback": "^3.0.0", "lodash._isiterateecall": "^3.0.0", @@ -10152,19 +10409,22 @@ "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash._isiterateecall": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.assign": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", "integrity": "sha512-/VVxzgGBmbphasTg51FrztxQJ/VgAUpol6zmJuSVSGcNg4g7FA4z7rQV8Ovr9V3vFBNWZhvKWHfpAytjTVUfFA==", "dev": true, + "license": "MIT", "dependencies": { "lodash._baseassign": "^3.0.0", "lodash._createassigner": "^3.0.0", @@ -10175,25 +10435,29 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isarray": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", "dev": true, + "license": "MIT", "dependencies": { "lodash._getnative": "^3.0.0", "lodash.isarguments": "^3.0.0", @@ -10204,12 +10468,14 @@ "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", "integrity": "sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -10221,75 +10487,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/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==" - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/log-update": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", @@ -10303,44 +10506,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/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/log-update/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/log-update/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/log-update/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10353,13 +10524,15 @@ "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "license": "Apache-2.0" }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -10369,6 +10542,7 @@ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -10380,6 +10554,7 @@ "version": "0.26.2", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.2.tgz", "integrity": "sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==", + "license": "MIT", "dependencies": { "sourcemap-codec": "^1.4.8" }, @@ -10392,6 +10567,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -10407,6 +10583,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -10415,13 +10592,15 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/make-fetch-happen": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", "devOptional": true, + "license": "ISC", "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", @@ -10449,6 +10628,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -10457,6 +10637,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -10468,6 +10649,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "license": "MIT", "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -10479,6 +10661,7 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -10488,6 +10671,7 @@ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -10496,22 +10680,28 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -10521,15 +10711,17 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "devOptional": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -10539,12 +10731,13 @@ } }, "node_modules/mime": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.3.tgz", - "integrity": "sha512-KgUb15Oorc0NEKPbvfa0wRU+PItIEZmiv+pyAO2i0oTIVTJhlzMclU7w4RXWQrSOVH5ax/p/CkIO7KI4OyFJTQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", + "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", "funding": [ "https://github.com/sponsors/broofa" ], + "license": "MIT", "bin": { "mime": "bin/cli.js" }, @@ -10557,6 +10750,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -10566,6 +10760,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -10577,6 +10772,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", "engines": { "node": ">=6" } @@ -10586,6 +10782,7 @@ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "dev": true, + "license": "MIT", "dependencies": { "schema-utils": "^4.0.0" }, @@ -10605,6 +10802,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -10623,13 +10821,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "devOptional": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10642,6 +10842,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10651,6 +10852,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "devOptional": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -10663,6 +10865,7 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "devOptional": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10675,6 +10878,7 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", "devOptional": true, + "license": "MIT", "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", @@ -10692,6 +10896,7 @@ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "devOptional": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10700,10 +10905,11 @@ } }, "node_modules/minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz", + "integrity": "sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg==", "devOptional": true, + "license": "MIT", "dependencies": { "jsonparse": "^1.3.1", "minipass": "^3.0.0" @@ -10714,6 +10920,7 @@ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "devOptional": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10726,6 +10933,7 @@ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "devOptional": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10737,13 +10945,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "devOptional": true, + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -10756,13 +10966,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "devOptional": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -10773,13 +10985,15 @@ "node_modules/monaco-editor": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.33.0.tgz", - "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==" + "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==", + "license": "MIT" }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -10788,13 +11002,15 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, + "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -10851,6 +11067,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", "bin": { "mustache": "bin/mustache" } @@ -10859,12 +11076,13 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -10872,6 +11090,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10884,6 +11103,7 @@ "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "iconv-lite": "^0.6.3", @@ -10901,6 +11121,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -10914,13 +11135,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "dev": true, + "license": "ISC", "optional": true }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -10929,13 +11152,15 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -10945,6 +11170,7 @@ "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-14.2.2.tgz", "integrity": "sha512-AqwHcMM6x+JkCHT++IsbulnTdyoXcC2Cr4tbPamuieacc77+fFbB195hdcqEFwsKX5410cymx/ZUyHird9rxlg==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.1.3", @@ -10990,6 +11216,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/ng-qrcode/-/ng-qrcode-7.0.0.tgz", "integrity": "sha512-Mx7nf8rtGMVYxGe2qfy8/JNiCnxKD7uFsqpP2Hm5eJSQrOEapQl9FR0yuK0I4MMQorJ7s8mZZDxmszQiH8R2Kg==", + "license": "MIT", "dependencies": { "qrcode": "^1.5.0", "tslib": "^2.4.0" @@ -11005,6 +11232,7 @@ "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "!win32" @@ -11019,12 +11247,14 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } @@ -11034,6 +11264,7 @@ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", "devOptional": true, + "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", @@ -11055,10 +11286,11 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", - "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, + "license": "MIT", "optional": true, "bin": { "node-gyp-build": "bin.js", @@ -11071,6 +11303,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "devOptional": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -11082,6 +11315,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11102,6 +11336,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "devOptional": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -11114,6 +11349,7 @@ "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz", "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==", "dev": true, + "license": "MIT", "dependencies": { "css-select": "^4.2.1", "he": "1.2.0" @@ -11123,6 +11359,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", "integrity": "sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==", + "license": "Apache-2.0", "dependencies": { "base64url": "^3.0.1", "buffer": "^6.0.3", @@ -11143,21 +11380,24 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "devOptional": true, + "license": "ISC", "dependencies": { "abbrev": "^1.0.0" }, @@ -11173,6 +11413,7 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-4.0.1.tgz", "integrity": "sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg==", "devOptional": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^5.0.0", "is-core-module": "^2.8.1", @@ -11188,6 +11429,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11197,6 +11439,7 @@ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11206,6 +11449,7 @@ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", "devOptional": true, + "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^1.0.1" } @@ -11215,6 +11459,7 @@ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-5.0.0.tgz", "integrity": "sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA==", "devOptional": true, + "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, @@ -11226,13 +11471,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/npm-package-arg": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.0.tgz", "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", "devOptional": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^5.0.0", "proc-log": "^2.0.1", @@ -11248,6 +11495,7 @@ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz", "integrity": "sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==", "devOptional": true, + "license": "ISC", "dependencies": { "glob": "^8.0.1", "ignore-walk": "^5.0.1", @@ -11266,6 +11514,7 @@ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz", "integrity": "sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==", "devOptional": true, + "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^2.0.0" }, @@ -11278,6 +11527,7 @@ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", "devOptional": true, + "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } @@ -11287,6 +11537,7 @@ "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz", "integrity": "sha512-IA8+tuv8KujbsbLQvselW2XQgmXWS47t3CB0ZrzsRZ82DbDfkcFunOaPm4X7qNuhMfq+FmV7hQT4iFVpHqV7mg==", "devOptional": true, + "license": "ISC", "dependencies": { "npm-install-checks": "^5.0.0", "npm-normalize-package-bin": "^1.0.1", @@ -11302,6 +11553,7 @@ "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz", "integrity": "sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw==", "devOptional": true, + "license": "ISC", "dependencies": { "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", @@ -11320,6 +11572,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -11333,6 +11586,7 @@ "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "deprecated": "This package is no longer supported.", "devOptional": true, + "license": "ISC", "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -11348,6 +11602,7 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -11356,10 +11611,11 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -11371,13 +11627,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -11390,6 +11648,7 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -11399,6 +11658,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "devOptional": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -11407,6 +11667,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -11422,6 +11683,7 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", "devOptional": true, + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -11439,6 +11701,7 @@ "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", "dev": true, + "license": "MIT", "bin": { "opencollective-postinstall": "index.js" } @@ -11448,6 +11711,7 @@ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true, + "license": "(WTFPL OR MIT)", "bin": { "opener": "bin/opener-bin.js" } @@ -11457,6 +11721,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -11473,6 +11738,7 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -11491,75 +11757,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ora/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==" - }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/os-name": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==", "dev": true, + "license": "MIT", "dependencies": { "macos-release": "^2.5.0", "windows-release": "^4.0.0" @@ -11576,6 +11779,7 @@ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11584,6 +11788,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -11598,6 +11803,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -11610,6 +11816,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "devOptional": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -11625,6 +11832,7 @@ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -11638,6 +11846,7 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -11646,6 +11855,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -11655,6 +11865,7 @@ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -11675,6 +11886,7 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -11684,6 +11896,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -11698,6 +11911,7 @@ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "4", @@ -11712,6 +11926,7 @@ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", "dev": true, + "license": "MIT", "dependencies": { "degenerator": "^3.0.2", "ip": "^1.1.5", @@ -11726,6 +11941,7 @@ "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.6.2.tgz", "integrity": "sha512-Gu8fU3GsvOPkak2CkbojR7vjs3k3P9cA6uazKTHdsdV0gpCEQq2opelnEv30KRQWgVzP5Vd/5umjcedma3MKtg==", "devOptional": true, + "license": "ISC", "dependencies": { "@npmcli/git": "^3.0.0", "@npmcli/installed-package-contents": "^1.0.7", @@ -11759,13 +11975,15 @@ "node_modules/pako": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -11778,6 +11996,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -11796,6 +12015,7 @@ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -11803,12 +12023,14 @@ "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" }, "node_modules/parse5-html-rewriting-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz", "integrity": "sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg==", + "license": "MIT", "dependencies": { "parse5": "^6.0.1", "parse5-sax-parser": "^6.0.1" @@ -11819,6 +12041,7 @@ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, + "license": "MIT", "dependencies": { "parse5": "^6.0.1" } @@ -11827,6 +12050,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz", "integrity": "sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg==", + "license": "MIT", "dependencies": { "parse5": "^6.0.1" } @@ -11836,6 +12060,7 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -11854,6 +12079,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", "engines": { "node": ">=8" } @@ -11863,6 +12089,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11872,6 +12099,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -11880,19 +12108,22 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -11901,6 +12132,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "license": "MIT", "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -11913,16 +12145,18 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -11935,6 +12169,7 @@ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -11947,6 +12182,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11956,6 +12192,7 @@ "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", "dev": true, + "license": "MIT", "dependencies": { "eventemitter-asyncresource": "^1.0.0", "hdr-histogram-js": "^2.0.1", @@ -11970,6 +12207,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -11982,6 +12220,7 @@ "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", "dev": true, + "license": "MIT", "dependencies": { "semver-compare": "^1.0.0" } @@ -11990,6 +12229,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -12013,6 +12253,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -12027,6 +12268,7 @@ "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12041,11 +12283,26 @@ "postcss": "^8.2" } }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-clamp": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12061,6 +12318,7 @@ "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12080,6 +12338,7 @@ "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12099,6 +12358,7 @@ "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12118,6 +12378,7 @@ "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12137,6 +12398,7 @@ "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12156,6 +12418,7 @@ "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -12170,11 +12433,26 @@ "postcss": "^8.3" } }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-dir-pseudo-class": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12189,11 +12467,26 @@ "postcss": "^8.2" } }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-double-position-gradients": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -12214,6 +12507,7 @@ "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12229,6 +12523,7 @@ "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -12239,11 +12534,26 @@ "postcss": "^8.4" } }, + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-focus-within": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -12254,11 +12564,26 @@ "postcss": "^8.4" } }, + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-font-variant": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", "dev": true, + "license": "MIT", "peerDependencies": { "postcss": "^8.1.0" } @@ -12268,6 +12593,7 @@ "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", "dev": true, + "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -12284,6 +12610,7 @@ "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12303,6 +12630,7 @@ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.0.0.tgz", "integrity": "sha512-Y20shPQ07RitgBGv2zvkEAu9bqvrD77C9axhj/aA1BQj4czape2MdClCExvB27EwYEJdGgKZBpKanb0t1rK2Kg==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -12320,6 +12648,7 @@ "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", "dev": true, + "license": "MIT", "peerDependencies": { "postcss": "^8.0.0" } @@ -12329,6 +12658,7 @@ "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -12349,6 +12679,7 @@ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.1.tgz", "integrity": "sha512-VRviFEyYlLjctSM93gAZtcJJ/iSkPZ79zWbN/1fSH+NisBByEiVLqpdVDrPLVSi8DX0oJo12kL/GppTBdKVXiQ==", "dev": true, + "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", "klona": "^2.0.5", @@ -12371,6 +12702,7 @@ "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", "dev": true, + "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -12383,6 +12715,7 @@ "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -12395,6 +12728,7 @@ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -12403,13 +12737,14 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz", + "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -12420,12 +12755,13 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dev": true, + "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -12439,6 +12775,7 @@ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, + "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -12454,6 +12791,7 @@ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -12469,6 +12807,37 @@ "postcss": "^8.2" } }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "license": "CC0-1.0", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-opacity-percentage": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", @@ -12484,6 +12853,7 @@ "url": "https://liberapay.com/mrcgrtz" } ], + "license": "MIT", "engines": { "node": "^12 || ^14 || >=16" }, @@ -12496,6 +12866,7 @@ "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12515,6 +12886,7 @@ "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", "dev": true, + "license": "MIT", "peerDependencies": { "postcss": "^8" } @@ -12524,6 +12896,7 @@ "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12543,6 +12916,7 @@ "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.0.tgz", "integrity": "sha512-leqiqLOellpLKfbHkD06E04P6d9ZQ24mat6hu4NSqun7WG0UhspHR5Myiv/510qouCjoo4+YJtNOqg5xHaFnCA==", "dev": true, + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-cascade-layers": "^1.0.5", "@csstools/postcss-color-function": "^1.1.1", @@ -12610,6 +12984,7 @@ "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", "dev": true, + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12624,11 +12999,26 @@ "postcss": "^8.2" } }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-replace-overflow-wrap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", "dev": true, + "license": "MIT", "peerDependencies": { "postcss": "^8.0.3" } @@ -12638,6 +13028,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", "dev": true, + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12652,11 +13043,26 @@ "postcss": "^8.2" } }, - "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -12670,6 +13076,7 @@ "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", "dev": true, + "license": "MIT", "dependencies": { "make-dir": "~3.1.0", "mime": "~2.5.2", @@ -12688,6 +13095,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -12698,6 +13106,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -12710,6 +13119,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -12721,7 +13131,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.1.2", @@ -12737,6 +13148,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -12752,6 +13164,7 @@ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -12764,6 +13177,7 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "devOptional": true, + "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } @@ -12772,6 +13186,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -12780,19 +13195,22 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "devOptional": true, + "license": "MIT", "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -12806,6 +13224,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -12819,6 +13238,7 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -12828,6 +13248,7 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^6.0.0", "debug": "4", @@ -12847,6 +13268,7 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -12856,6 +13278,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, + "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -12870,6 +13293,7 @@ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "4", @@ -12883,20 +13307,23 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -12906,17 +13333,18 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/qrcode": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz", - "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", "dependencies": { "dijkstrajs": "^1.0.1", - "encode-utf8": "^1.0.3", "pngjs": "^5.0.0", "yargs": "^15.3.1" }, @@ -12927,50 +13355,22 @@ "node": ">=10.13.0" } }, - "node_modules/qrcode/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/qrcode/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, - "node_modules/qrcode/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/qrcode/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==" - }, "node_modules/qrcode/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -12983,12 +13383,14 @@ "node_modules/qrcode/node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "license": "ISC" }, "node_modules/qrcode/node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -13010,6 +13412,7 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -13019,10 +13422,11 @@ } }, "node_modules/qs": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", - "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -13051,13 +13455,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -13067,6 +13473,7 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -13076,6 +13483,7 @@ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -13091,6 +13499,7 @@ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", "dev": true, + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -13111,6 +13520,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13127,6 +13537,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -13135,13 +13546,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/raw-loader/node_modules/loader-utils": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -13156,6 +13569,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13174,6 +13588,7 @@ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^2.3.0" } @@ -13184,6 +13599,7 @@ "integrity": "sha512-BSzugrt4kQ/Z0krro8zhTwV1Kd79ue25IhNN/VtHFy1mG/6Tluyi+msc0UpwaoQzxSHa28mntAjIZY6kEgfR9Q==", "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", "devOptional": true, + "license": "ISC", "dependencies": { "glob": "^8.0.1", "json-parse-even-better-errors": "^2.3.1", @@ -13199,6 +13615,7 @@ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz", "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==", "devOptional": true, + "license": "ISC", "dependencies": { "json-parse-even-better-errors": "^2.3.0", "npm-normalize-package-bin": "^1.0.1" @@ -13212,6 +13629,7 @@ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", "devOptional": true, + "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } @@ -13220,6 +13638,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -13234,6 +13653,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "devOptional": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -13245,19 +13665,22 @@ "version": "0.1.14", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -13269,13 +13692,15 @@ "version": "0.13.9", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } @@ -13284,18 +13709,20 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -13303,31 +13730,44 @@ "node": ">=4" } }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13336,6 +13776,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13343,19 +13784,22 @@ "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "license": "ISC" }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "devOptional": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -13373,6 +13817,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13382,6 +13827,7 @@ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", "dev": true, + "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", "convert-source-map": "^1.7.0", @@ -13398,6 +13844,7 @@ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -13412,6 +13859,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -13420,6 +13868,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -13433,6 +13882,7 @@ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -13442,6 +13892,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "devOptional": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -13451,7 +13902,8 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", @@ -13459,6 +13911,7 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "devOptional": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -13474,6 +13927,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "devOptional": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -13485,6 +13939,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "devOptional": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -13505,6 +13960,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "devOptional": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -13516,16 +13972,18 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "license": "MIT", "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "dev": true, + "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -13541,6 +13999,7 @@ "resolved": "https://registry.npmjs.org/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz", "integrity": "sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.0.9", "source-map-resolve": "^0.6.0" @@ -13563,6 +14022,7 @@ "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", "dev": true, + "license": "MIT", "engines": { "node": "0.12.* || 4.* || 6.* || >= 7.*" } @@ -13572,6 +14032,7 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -13595,6 +14056,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -13603,6 +14065,7 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } @@ -13624,19 +14087,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/sass": { "version": "1.54.4", "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.4.tgz", "integrity": "sha512-3tmF16yvnBwtlPrNBHw/H907j8MlOX8aTBnlNX1yrKx24RKcJGPyLhFUwkoKBKesR3unP93/2z14Ll8NicwQUA==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -13654,6 +14120,7 @@ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.0.2.tgz", "integrity": "sha512-BbiqbVmbfJaWVeOOAu2o7DhYWtcNmTfvroVgFXa6k2hHheMxNAeDHLNoDy/Q5aoaVlz0LH+MbMktKwm9vN/j8Q==", "dev": true, + "license": "MIT", "dependencies": { "klona": "^2.0.4", "neo-async": "^2.6.2" @@ -13691,13 +14158,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.5", "ajv": "^6.12.4", @@ -13716,6 +14185,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13732,6 +14202,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -13740,19 +14211,22 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/selfsigned": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -13766,6 +14240,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "devOptional": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -13780,13 +14255,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/semver-regex": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -13799,6 +14276,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "devOptional": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -13810,13 +14288,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -13841,6 +14321,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -13849,13 +14330,25 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -13867,13 +14360,15 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -13883,6 +14378,7 @@ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -13901,6 +14397,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -13910,6 +14407,7 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -13919,6 +14417,7 @@ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, + "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -13933,39 +14432,44 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, + "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -13974,13 +14478,15 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -13997,12 +14503,14 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -14016,6 +14524,7 @@ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -14028,6 +14537,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -14040,6 +14550,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14049,6 +14560,7 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -14065,13 +14577,15 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" }, "node_modules/sirv": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, + "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -14086,6 +14600,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -14098,6 +14613,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -14110,44 +14626,12 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/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/slice-ansi/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/slice-ansi/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/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -14158,6 +14642,7 @@ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, + "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -14169,6 +14654,7 @@ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "devOptional": true, + "license": "MIT", "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -14183,6 +14669,7 @@ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "devOptional": true, + "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -14196,15 +14683,17 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -14214,6 +14703,7 @@ "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.0.tgz", "integrity": "sha512-i3KVgM3+QPAHNbGavK+VBq03YoJl24m9JWNbLgsjTj8aJzXG9M61bantBTNBt7CNwY2FYf+RJRYJ3pzalKjIrw==", "dev": true, + "license": "MIT", "dependencies": { "abab": "^2.0.6", "iconv-lite": "^0.6.3", @@ -14235,6 +14725,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -14248,6 +14739,7 @@ "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, + "license": "MIT", "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0" @@ -14258,6 +14750,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -14268,6 +14761,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -14276,13 +14770,15 @@ "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "license": "MIT" }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -14292,29 +14788,33 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "devOptional": true + "devOptional": true, + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "devOptional": true, + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "devOptional": true + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "devOptional": true, + "license": "CC0-1.0" }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -14331,6 +14831,7 @@ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -14345,6 +14846,7 @@ "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, + "license": "ISC", "dependencies": { "readable-stream": "^3.0.0" } @@ -14353,24 +14855,28 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "devOptional": true + "devOptional": true, + "license": "BSD-3-Clause" }, "node_modules/ssh-config": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/ssh-config/-/ssh-config-1.1.6.tgz", "integrity": "sha512-ZPO9rECxzs5JIQ6G/2EfL1I9ho/BVZkx9HRKn8+0af7QgwAmumQ7XBFP1ggMyPMo+/tUbmv0HFdv4qifdO/9JA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ssr-window": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", - "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==", + "license": "MIT" }, "node_modules/ssri": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", "devOptional": true, + "license": "ISC", "dependencies": { "minipass": "^3.1.1" }, @@ -14383,6 +14889,7 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -14392,6 +14899,7 @@ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", "dev": true, + "license": "MIT", "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" @@ -14402,6 +14910,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -14416,13 +14925,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stream-combiner2/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -14431,6 +14942,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -14440,6 +14952,7 @@ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6.19" } @@ -14448,6 +14961,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -14461,6 +14975,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -14473,6 +14988,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -14482,6 +14998,7 @@ "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.59.0.tgz", "integrity": "sha512-lQ9w/XIOH5ZHVNuNbWW8D822r+/wBSO/d6XvtyHLF7LW4KaCIDeVbvn5DF8fGCJAUCwVhVi/h6J0NUcnylUEjg==", "dev": true, + "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.0.1", "debug": "^4.3.2", @@ -14504,6 +15021,7 @@ "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-7.0.0.tgz", "integrity": "sha512-WTbtLrNfOfLgzTaR9Lj/BPhQroKk/LC1hfTXSUbrxmxgfUo3Y3LpmKRVA2R1XbjvTAvOfaian9vOyfv1z99E+A==", "dev": true, + "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", "klona": "^2.0.5", @@ -14526,6 +15044,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14537,6 +15056,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14557,6 +15077,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14568,7 +15089,8 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/superagent": { "version": "5.3.1", @@ -14576,6 +15098,7 @@ "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dev": true, + "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.2", @@ -14598,6 +15121,7 @@ "resolved": "https://registry.npmjs.org/superagent-proxy/-/superagent-proxy-3.0.0.tgz", "integrity": "sha512-wAlRInOeDFyd9pyonrkJspdRAxdLrcsZ6aSnS+8+nu4x1aXbz6FWSTT9M6Ibze+eG60szlL7JA8wEIV7bPWuyQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.2", "proxy-agent": "^5.0.0" @@ -14614,6 +15138,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -14622,15 +15147,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -14638,6 +15163,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -14660,6 +15186,7 @@ } ], "hasInstallScript": true, + "license": "MIT", "dependencies": { "dom7": "^4.0.4", "ssr-window": "^4.0.2" @@ -14673,6 +15200,7 @@ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10" } @@ -14682,6 +15210,7 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -14691,6 +15220,7 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "devOptional": true, + "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -14708,6 +15238,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=8" } @@ -14716,13 +15247,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/terser": { "version": "5.14.2", "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -14741,6 +15274,7 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -14775,6 +15309,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14791,6 +15326,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -14799,19 +15335,22 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -14826,10 +15365,11 @@ } }, "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -14847,13 +15387,15 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -14868,6 +15410,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14879,6 +15422,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14899,6 +15443,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14916,25 +15461,29 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "devOptional": true, + "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -14942,20 +15491,12 @@ "node": ">=0.6.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "devOptional": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -14968,6 +15509,7 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6" } @@ -14977,6 +15519,7 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -14986,14 +15529,16 @@ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, + "license": "MIT", "bin": { "tree-kill": "cli.js" } }, "node_modules/ts-matches": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-5.5.1.tgz", - "integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.2.1.tgz", + "integrity": "sha512-qdnMgTHsGCEGGK6QiaNMY2vD9eQtRp2Q+pAxcOAzxHJKDKTBYsc1ISTg1zp8H2+EmtCB0eko/1TwYUA5/mUGug==", + "license": "MIT" }, "node_modules/ts-morph": { "version": "23.0.0", @@ -15011,6 +15556,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -15050,9 +15596,9 @@ } }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/tslint": { @@ -15061,6 +15607,7 @@ "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -15086,11 +15633,25 @@ "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" } }, + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/tslint/node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -15100,6 +15661,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -15110,15 +15672,49 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, "node_modules/tslint/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tslint/node_modules/glob": { "version": "7.2.3", @@ -15126,6 +15722,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15141,11 +15738,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/tslint/node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -15159,6 +15767,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -15171,6 +15780,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -15183,6 +15793,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -15191,19 +15802,35 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, "node_modules/tslint/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/tsutils": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -15215,13 +15842,15 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2" }, @@ -15234,6 +15863,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "devOptional": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -15246,6 +15876,7 @@ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -15258,13 +15889,15 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, + "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } @@ -15274,6 +15907,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15283,10 +15917,11 @@ } }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15296,6 +15931,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -15305,10 +15941,11 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15318,6 +15955,7 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15327,6 +15965,7 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "devOptional": true, + "license": "ISC", "dependencies": { "unique-slug": "^2.0.0" } @@ -15336,6 +15975,7 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "devOptional": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" } @@ -15345,6 +15985,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -15354,6 +15995,7 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -15363,14 +16005,15 @@ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -15386,9 +16029,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -15401,6 +16045,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -15408,13 +16053,15 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -15423,6 +16070,7 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -15431,13 +16079,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -15448,6 +16098,7 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", "devOptional": true, + "license": "ISC", "dependencies": { "builtins": "^5.0.0" }, @@ -15460,6 +16111,7 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -15470,6 +16122,7 @@ "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", "deprecated": "The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm.", "dev": true, + "license": "MIT", "dependencies": { "acorn": "^8.7.0", "acorn-walk": "^8.2.0" @@ -15482,10 +16135,11 @@ } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -15499,6 +16153,7 @@ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, + "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -15507,27 +16162,28 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -15564,6 +16220,7 @@ "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "dev": true, + "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", @@ -15590,6 +16247,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -15599,6 +16257,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -15611,6 +16270,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -15634,6 +16294,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -15653,6 +16314,7 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz", "integrity": "sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -15708,6 +16370,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -15727,6 +16390,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -15748,6 +16412,7 @@ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" @@ -15761,6 +16426,7 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -15770,6 +16436,7 @@ "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", "dev": true, + "license": "MIT", "dependencies": { "typed-assert": "^1.0.8" }, @@ -15787,10 +16454,11 @@ } }, "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/webpack/node_modules/ajv": { @@ -15798,6 +16466,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -15815,6 +16484,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peer": true, "peerDependencies": { "ajv": "^6.9.1" @@ -15825,6 +16495,7 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, + "license": "MIT", "peer": true }, "node_modules/webpack/node_modules/schema-utils": { @@ -15832,6 +16503,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -15851,6 +16523,7 @@ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -15865,6 +16538,7 @@ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -15874,6 +16548,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "devOptional": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -15887,13 +16562,15 @@ "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "license": "ISC" }, "node_modules/which-pm-runs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15903,6 +16580,7 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "devOptional": true, + "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -15911,13 +16589,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/windows-release": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^4.0.2" }, @@ -15933,6 +16613,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -15956,6 +16637,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -15971,6 +16653,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=8.12.0" } @@ -15980,6 +16663,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -15989,6 +16673,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -16001,50 +16686,19 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/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==", - "devOptional": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/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==", - "devOptional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/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==", - "devOptional": true - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -16057,6 +16711,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -16078,6 +16733,7 @@ "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -16087,6 +16743,7 @@ "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", "dev": true, + "license": "MIT", "dependencies": { "cuint": "^0.2.2" } @@ -16096,6 +16753,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -16104,13 +16762,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 6" } @@ -16120,6 +16780,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", "devOptional": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -16138,6 +16799,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -16147,6 +16809,7 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -16156,6 +16819,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -16167,6 +16831,7 @@ "version": "0.11.8", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", "integrity": "sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" } diff --git a/web/package.json b/web/package.json index 3f3709e11..ecc253904 100644 --- a/web/package.json +++ b/web/package.json @@ -52,6 +52,7 @@ "@start9labs/emver": "^0.1.5", "@start9labs/start-sdk": "file:../sdk/baseDist", "@taiga-ui/addon-charts": "3.96.0", + "@taiga-ui/addon-commerce": "3.96.0", "@taiga-ui/cdk": "3.96.0", "@taiga-ui/core": "3.96.0", "@taiga-ui/experimental": "3.96.0", @@ -83,7 +84,7 @@ "pbkdf2": "^3.1.2", "rxjs": "^7.8.1", "swiper": "^8.2.4", - "ts-matches": "^5.5.1", + "ts-matches": "^6.1.0", "tslib": "^2.3.0", "uuid": "^8.3.2", "zone.js": "^0.11.5" diff --git a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts index d9bc2dff3..39a69037f 100644 --- a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts @@ -6,7 +6,7 @@ import cbor from 'cbor' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ConfigService } from 'src/app/services/config.service' import { SideloadService } from './sideload.service' -import { firstValueFrom } from 'rxjs' +import { filter, firstValueFrom } from 'rxjs' import mime from 'mime' interface Positions { @@ -124,7 +124,7 @@ export class SideloadPage { this.api .uploadPackage(res.upload, this.toUpload.file!) .catch(e => console.error(e)) - await firstValueFrom(this.sideloadService.websocketConnected$) + await firstValueFrom(this.progress$.pipe(filter(Boolean))) } catch (e: any) { this.errorService.handleError(e) } finally { diff --git a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts index 79f871bba..d157272ff 100644 --- a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts +++ b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core' import { T } from '@start9labs/start-sdk' -import { endWith, ReplaySubject, shareReplay, Subject, switchMap } from 'rxjs' +import { BehaviorSubject, endWith, shareReplay, Subject, switchMap } from 'rxjs' import { ApiService } from 'src/app/services/api/embassy-api.service' @Injectable({ @@ -9,17 +9,9 @@ import { ApiService } from 'src/app/services/api/embassy-api.service' export class SideloadService { private readonly guid$ = new Subject() - readonly websocketConnected$ = new ReplaySubject() - readonly progress$ = this.guid$.pipe( switchMap(guid => - this.api - .openWebsocket$(guid, { - openObserver: { - next: () => this.websocketConnected$.next(''), - }, - }) - .pipe(endWith(null)), + this.api.openWebsocket$(guid).pipe(endWith(null)), ), shareReplay(1), ) From 45ca9405d363d3d20305fcaeaded2de0be534473 Mon Sep 17 00:00:00 2001 From: Dominion5254 Date: Thu, 9 Jan 2025 13:43:53 -0700 Subject: [PATCH 05/35] Feat/test smtp (#2806) * add test-smtp server subcommand * return error is password is None * fix return type * borrow variables * convert args to &str * Tuple needs to have the same types apparently * Clone instead * fix formatting * improve test email body * Update core/startos/src/system.rs Co-authored-by: kn0wmad <39687477+kn0wmad@users.noreply.github.com> * add tls connection * remove commented code * use aidens mail-send fork --------- Co-authored-by: kn0wmad <39687477+kn0wmad@users.noreply.github.com> --- core/Cargo.lock | 499 ++++++++++++++++-- core/models/Cargo.toml | 1 + core/models/src/errors.rs | 5 + core/startos/Cargo.toml | 3 + core/startos/src/lib.rs | 7 + core/startos/src/lxc/dev.rs | 6 +- core/startos/src/lxc/mod.rs | 3 +- core/startos/src/net/vhost.rs | 10 +- core/startos/src/notifications.rs | 4 +- .../src/service/effects/subcontainer/mod.rs | 5 +- core/startos/src/system.rs | 57 ++ 11 files changed, 535 insertions(+), 65 deletions(-) diff --git a/core/Cargo.lock b/core/Cargo.lock index cdafe81a1..48c26ce61 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -42,6 +42,17 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + [[package]] name = "ahash" version = "0.7.8" @@ -166,6 +177,15 @@ version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -205,7 +225,7 @@ dependencies = [ "nom 7.1.3", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -244,12 +264,12 @@ dependencies = [ "log", "pem", "rcgen", - "ring", - "rustls 0.23.17", + "ring 0.17.8", + "rustls 0.23.20", "rustls-pemfile 2.2.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "x509-parser", ] @@ -491,7 +511,7 @@ dependencies = [ "deku", "flate2", "rustc-hash", - "thiserror", + "thiserror 1.0.69", "tracing", "xz2", "zstd", @@ -521,7 +541,7 @@ checksum = "be5951c75bdabb58753d140dd5802f12ff3a483cb2e16fb5276e111b94b19e87" dependencies = [ "concurrent-queue 1.2.4", "event-listener", - "spin", + "spin 0.9.8", ] [[package]] @@ -758,6 +778,27 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "cache-padded" version = "1.3.0" @@ -1361,6 +1402,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + [[package]] name = "deku" version = "0.17.0" @@ -1433,6 +1480,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "derive_more" version = "0.99.18" @@ -1837,7 +1895,7 @@ checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", - "spin", + "spin 0.9.8", ] [[package]] @@ -2038,6 +2096,16 @@ dependencies = [ "webpki-roots 0.26.6", ] +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -2252,6 +2320,57 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hickory-proto" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447afdcdb8afb9d0a852af6dc65d9b285ce720ed7a59e42a8bf2e931c67bc1b5" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 1.0.3", + "ipnet", + "once_cell", + "rand 0.8.5", + "ring 0.16.20", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "thiserror 1.0.69", + "tinyvec", + "tokio", + "tokio-rustls 0.24.1", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand 0.8.5", + "resolv-conf", + "rustls 0.21.12", + "smallvec", + "thiserror 1.0.69", + "tokio", + "tokio-rustls 0.24.1", + "tracing", +] + [[package]] name = "hifijson" version = "0.2.2" @@ -2285,6 +2404,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "http" version = "0.2.12" @@ -2414,7 +2544,7 @@ dependencies = [ "http 1.1.0", "hyper 1.5.1", "hyper-util", - "rustls 0.23.17", + "rustls 0.23.20", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -2781,6 +2911,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + [[package]] name = "ipnet" version = "2.10.1" @@ -2824,7 +2966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ea1dc4bf0fb4904ba83ffdb98af3d9c325274e92e6e295e4151e86c96363e04" dependencies = [ "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2939,7 +3081,7 @@ dependencies = [ "regex", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -2969,7 +3111,7 @@ dependencies = [ "imbl", "imbl-value", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3045,7 +3187,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin", + "spin 0.9.8", ] [[package]] @@ -3117,6 +3259,12 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e281a65eeba3d4503a2839252f86374528f9ceafe6fed97c1d3b52e1fb625c1" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -3145,12 +3293,37 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + [[package]] name = "lzma-sys" version = "0.1.20" @@ -3162,6 +3335,70 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "mail-auth" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd9d657de66a3d5ac360c3eab8c9f5cac2565f2b97cc032d5de4c900ef470de" +dependencies = [ + "ahash 0.8.11", + "flate2", + "hickory-resolver", + "lru-cache", + "mail-builder", + "mail-parser", + "parking_lot", + "quick-xml", + "ring 0.17.8", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "zip", +] + +[[package]] +name = "mail-builder" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f5871d5270ed80f2ee750b95600c8d69b05f8653ad3be913b2ad2e924fefcb" +dependencies = [ + "gethostname", +] + +[[package]] +name = "mail-parser" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c3b9e5d8b17faf573330bbc43b37d6e918c0a3bf8a88e7d0a220ebc84af9fc" +dependencies = [ + "encoding_rs", +] + +[[package]] +name = "mail-send" +version = "0.4.9" +source = "git+https://github.com/dr-bonez/mail-send.git?branch=main#57545dadab5808d59145d133de64f81b8ba01979" +dependencies = [ + "base64 0.22.1", + "gethostname", + "mail-auth", + "mail-builder", + "md5", + "rand 0.8.5", + "rustls 0.23.20", + "rustls-pki-types", + "smtp-proto", + "tokio", + "tokio-rustls 0.26.0", + "webpki-roots 0.26.6", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.1.0" @@ -3187,7 +3424,7 @@ dependencies = [ "bitvec 1.0.1", "serde", "serde-big-array", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3200,6 +3437,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.7.4" @@ -3301,11 +3544,12 @@ dependencies = [ "regex", "reqwest", "rpc-toolkit", + "rustls 0.23.20", "serde", "serde_json", "sqlx", "ssh-key", - "thiserror", + "thiserror 1.0.69", "tokio", "torut", "tracing", @@ -3599,7 +3843,7 @@ dependencies = [ "byteorder", "md-5", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3751,7 +3995,7 @@ dependencies = [ "patch-db-macro", "serde", "serde_cbor", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-error", @@ -3818,7 +4062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] @@ -4138,6 +4382,15 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.37" @@ -4265,7 +4518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1" dependencies = [ "pem", - "ring", + "ring 0.17.8", "time", "yasna", ] @@ -4302,7 +4555,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4409,6 +4662,16 @@ dependencies = [ "url", ] +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -4419,6 +4682,21 @@ dependencies = [ "subtle", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + [[package]] name = "ring" version = "0.17.8" @@ -4429,8 +4707,8 @@ dependencies = [ "cfg-if", "getrandom 0.2.15", "libc", - "spin", - "untrusted", + "spin 0.9.8", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -4466,7 +4744,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "url", @@ -4564,7 +4842,8 @@ version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ - "ring", + "log", + "ring 0.17.8", "rustls-webpki 0.101.7", "sct", ] @@ -4576,7 +4855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", - "ring", + "ring 0.17.8", "rustls-pki-types", "rustls-webpki 0.102.8", "subtle", @@ -4585,14 +4864,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.17" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "aws-lc-rs", "log", "once_cell", - "ring", + "ring 0.17.8", "rustls-pki-types", "rustls-webpki 0.102.8", "subtle", @@ -4619,9 +4898,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" [[package]] name = "rustls-webpki" @@ -4629,8 +4908,8 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -4640,9 +4919,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "aws-lc-rs", - "ring", + "ring 0.17.8", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -4674,7 +4953,7 @@ dependencies = [ "futures-util", "pin-project", "thingbuf", - "thiserror", + "thiserror 1.0.69", "unicode-segmentation", "unicode-width 0.1.12", ] @@ -4715,8 +4994,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -4833,7 +5112,7 @@ checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" dependencies = [ "percent-encoding", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5016,6 +5295,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "simple-logging" version = "2.0.2" @@ -5054,6 +5339,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "smtp-proto" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b8ad3dd187f0d4debab02ad65405a9919d6a4f7bce25bd64a258781063a53a" + [[package]] name = "socket2" version = "0.5.7" @@ -5064,6 +5355,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" @@ -5141,7 +5438,7 @@ dependencies = [ "sha2 0.10.8", "smallvec", "sqlformat", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -5226,7 +5523,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 1.0.69", "tracing", "whoami", ] @@ -5265,7 +5562,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 1.0.69", "tracing", "whoami", ] @@ -5373,7 +5670,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "start-os" version = "0.3.6-alpha.9" dependencies = [ - "aes", + "aes 0.7.5", "async-acme", "async-compression", "async-stream", @@ -5433,6 +5730,7 @@ dependencies = [ "lazy_static", "libc", "log", + "mail-send", "mbrman", "models", "new_mime_guess", @@ -5461,6 +5759,8 @@ dependencies = [ "rpassword", "rpc-toolkit", "rust-argon2", + "rustls 0.23.20", + "rustls-pki-types", "rustyline-async", "semver", "serde", @@ -5478,7 +5778,7 @@ dependencies = [ "ssh-key", "tar", "textwrap", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-rustls 0.26.0", "tokio-socks", @@ -5699,7 +5999,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f5383f3e0071702bf93ab5ee99b52d26936be9dedd9413067cbdcddcb6141a" +dependencies = [ + "thiserror-impl 2.0.8", ] [[package]] @@ -5713,6 +6022,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f357fcec90b3caef6623a099691be676d033b40a058ac95d2a6ade6fa0c943" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thread-id" version = "3.3.0" @@ -5849,6 +6169,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.25.0" @@ -5866,7 +6196,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.17", + "rustls 0.23.20", "rustls-pki-types", "tokio", ] @@ -5879,7 +6209,7 @@ checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" dependencies = [ "either", "futures-util", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -6221,7 +6551,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "smallvec", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -6242,7 +6572,7 @@ dependencies = [ "futures-executor", "futures-util", "serde", - "thiserror", + "thiserror 1.0.69", "time", "tokio", "toml 0.7.8", @@ -6261,7 +6591,7 @@ name = "ts-rs" version = "8.1.0" source = "git+https://github.com/dr-bonez/ts-rs.git?branch=feature%2Ftop-level-as#7ae88ade90b5e724159048a663a0bdb04bed27f7" dependencies = [ - "thiserror", + "thiserror 1.0.69", "ts-rs-macros", ] @@ -6303,7 +6633,7 @@ dependencies = [ "native-tls", "rand 0.8.5", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", ] @@ -6322,7 +6652,7 @@ dependencies = [ "log", "rand 0.8.5", "sha1", - "thiserror", + "thiserror 1.0.69", "utf-8", ] @@ -6443,6 +6773,12 @@ dependencies = [ "libc", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -6701,6 +7037,12 @@ dependencies = [ "wasite", ] +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + [[package]] name = "winapi" version = "0.3.9" @@ -6937,6 +7279,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -6977,7 +7329,7 @@ dependencies = [ "nom 7.1.3", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -7019,7 +7371,7 @@ dependencies = [ "anyhow", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7151,6 +7503,49 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zip" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45" +dependencies = [ + "aes 0.8.4", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "hmac", + "indexmap 2.6.0", + "lzma-rs", + "memchr", + "pbkdf2", + "rand 0.8.5", + "sha1", + "thiserror 2.0.8", + "time", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] + [[package]] name = "zstd" version = "0.13.2" diff --git a/core/models/Cargo.toml b/core/models/Cargo.toml index 44295745d..f5637c22d 100644 --- a/core/models/Cargo.toml +++ b/core/models/Cargo.toml @@ -25,6 +25,7 @@ rand = "0.8.5" regex = "1.10.2" reqwest = "0.12" rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "refactor/no-dyn-ctx" } +rustls = "0.23" serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" sqlx = { version = "0.7.2", features = [ diff --git a/core/models/src/errors.rs b/core/models/src/errors.rs index 2077a8bbd..b57312f05 100644 --- a/core/models/src/errors.rs +++ b/core/models/src/errors.rs @@ -327,6 +327,11 @@ impl From for Error { Error::new(e, ErrorKind::Tor) } } +impl From for Error { + fn from(e: rustls::Error) -> Self { + Error::new(e, ErrorKind::OpenSsl) + } +} impl From for Error { fn from(value: patch_db::value::Error) -> Self { match value.kind { diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index cba5bc6dc..0cde21e72 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -217,6 +217,9 @@ url = { version = "2.4.1", features = ["serde"] } urlencoding = "2.1.3" uuid = { version = "1.4.1", features = ["v4"] } zeroize = "1.6.0" +mail-send = { git = "https://github.com/dr-bonez/mail-send.git", branch = "main" } +rustls = "0.23.20" +rustls-pki-types = { version = "1.10.1", features = ["alloc"]} [profile.test] opt-level = 3 diff --git a/core/startos/src/lib.rs b/core/startos/src/lib.rs index 3c5875e36..8033f5e09 100644 --- a/core/startos/src/lib.rs +++ b/core/startos/src/lib.rs @@ -295,6 +295,13 @@ pub fn server() -> ParentHandler { .with_about("Set system smtp server and credentials") .with_call_remote::() ) + .subcommand( + "test-smtp", + from_fn_async(system::test_system_smtp) + .no_display() + .with_about("Send test email using system smtp server and credentials") + .with_call_remote::() + ) .subcommand( "clear-smtp", from_fn_async(system::clear_system_smtp) diff --git a/core/startos/src/lxc/dev.rs b/core/startos/src/lxc/dev.rs index 248546d88..a918672da 100644 --- a/core/startos/src/lxc/dev.rs +++ b/core/startos/src/lxc/dev.rs @@ -8,13 +8,11 @@ use rpc_toolkit::{ use serde::{Deserialize, Serialize}; use ts_rs::TS; +use crate::context::{CliContext, RpcContext}; use crate::lxc::{ContainerId, LxcConfig}; use crate::prelude::*; use crate::rpc_continuations::Guid; -use crate::{ - context::{CliContext, RpcContext}, - service::ServiceStats, -}; +use crate::service::ServiceStats; pub fn lxc() -> ParentHandler { ParentHandler::new() diff --git a/core/startos/src/lxc/mod.rs b/core/startos/src/lxc/mod.rs index c0fb6eaba..60f9f4301 100644 --- a/core/startos/src/lxc/mod.rs +++ b/core/startos/src/lxc/mod.rs @@ -1,8 +1,9 @@ +use std::collections::BTreeSet; +use std::ffi::OsString; use std::net::Ipv4Addr; use std::path::Path; use std::sync::{Arc, Weak}; use std::time::Duration; -use std::{collections::BTreeSet, ffi::OsString}; use clap::builder::ValueParserFactory; use futures::{AsyncWriteExt, StreamExt}; diff --git a/core/startos/src/net/vhost.rs b/core/startos/src/net/vhost.rs index 7d48b1469..fb7c6f957 100644 --- a/core/startos/src/net/vhost.rs +++ b/core/startos/src/net/vhost.rs @@ -35,8 +35,8 @@ use crate::net::acme::AcmeCertCache; use crate::net::static_server::server_error; use crate::prelude::*; use crate::util::io::BackTrackingIO; -use crate::util::sync::SyncMutex; use crate::util::serde::MaybeUtf8String; +use crate::util::sync::SyncMutex; #[derive(Debug)] struct SingleCertResolver(Arc); @@ -126,7 +126,11 @@ struct VHostServer { } impl VHostServer { #[instrument(skip_all)] - async fn new(port: u16, db: TypedPatchDb, crypto_provider: Arc) -> Result { + async fn new( + port: u16, + db: TypedPatchDb, + crypto_provider: Arc, + ) -> Result { let acme_tls_alpn_cache = Arc::new(SyncMutex::new(BTreeMap::< InternedString, watch::Receiver>>, @@ -273,7 +277,7 @@ impl VHostServer { let domains = [domain.to_string()]; let (send, recv) = watch::channel(None); acme_tls_alpn_cache.mutate(|c| c.insert(domain.clone(), recv)); - let cert = + let cert = async_acme::rustls_helper::order( |_, cert| { send.send_replace(Some(Arc::new(cert))); diff --git a/core/startos/src/notifications.rs b/core/startos/src/notifications.rs index 4b45531a4..19376026d 100644 --- a/core/startos/src/notifications.rs +++ b/core/startos/src/notifications.rs @@ -13,11 +13,11 @@ use serde::{Deserialize, Serialize}; use tracing::instrument; use ts_rs::TS; +use crate::backup::BackupReport; use crate::context::{CliContext, RpcContext}; -use crate::db::model::DatabaseModel; +use crate::db::model::{Database, DatabaseModel}; use crate::prelude::*; use crate::util::serde::HandlerExtSerde; -use crate::{backup::BackupReport, db::model::Database}; // #[command(subcommands(list, delete, delete_before, create))] pub fn notification() -> ParentHandler { diff --git a/core/startos/src/service/effects/subcontainer/mod.rs b/core/startos/src/service/effects/subcontainer/mod.rs index 65fcbd387..943c70dbf 100644 --- a/core/startos/src/service/effects/subcontainer/mod.rs +++ b/core/startos/src/service/effects/subcontainer/mod.rs @@ -4,12 +4,11 @@ use imbl_value::InternedString; use models::ImageId; use tokio::process::Command; +use crate::disk::mount::filesystem::overlayfs::OverlayGuard; use crate::rpc_continuations::Guid; use crate::service::effects::prelude::*; +use crate::service::persistent_container::Subcontainer; use crate::util::Invoke; -use crate::{ - disk::mount::filesystem::overlayfs::OverlayGuard, service::persistent_container::Subcontainer, -}; #[cfg(feature = "container-runtime")] mod sync; diff --git a/core/startos/src/system.rs b/core/startos/src/system.rs index e64f30e98..d05af09b5 100644 --- a/core/startos/src/system.rs +++ b/core/startos/src/system.rs @@ -1,12 +1,18 @@ use std::collections::BTreeSet; use std::fmt; +use std::sync::Arc; use chrono::Utc; use clap::Parser; use color_eyre::eyre::eyre; use futures::FutureExt; use imbl::vector; +use mail_send::mail_builder::MessageBuilder; +use mail_send::SmtpClientBuilder; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; +use rustls::crypto::CryptoProvider; +use rustls::RootCertStore; +use rustls_pki_types::CertificateDer; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use tokio::process::Command; use tokio::sync::broadcast::Receiver; @@ -871,6 +877,57 @@ pub async fn clear_system_smtp(ctx: RpcContext) -> Result<(), Error> { } Ok(()) } +pub async fn test_system_smtp( + _: RpcContext, + SmtpValue { + server, + port, + from, + login, + password, + }: SmtpValue, +) -> Result<(), Error> { + use rustls_pki_types::pem::PemObject; + + let Some(pass_val) = password else { + return Err(Error::new( + eyre!("mail-send requires a password"), + ErrorKind::InvalidRequest, + )); + }; + + let mut root_cert_store = RootCertStore::empty(); + let pem = tokio::fs::read("/etc/ssl/certs/ca-certificates.crt").await?; + for cert in CertificateDer::pem_slice_iter(&pem) { + root_cert_store.add_parsable_certificates([cert.with_kind(ErrorKind::OpenSsl)?]); + } + + let cfg = Arc::new( + rustls::ClientConfig::builder_with_provider(Arc::new( + rustls::crypto::ring::default_provider(), + )) + .with_safe_default_protocol_versions()? + .with_root_certificates(root_cert_store) + .with_no_client_auth(), + ); + let client = SmtpClientBuilder::new_with_tls_config(server, port, cfg) + .implicit_tls(false) + .credentials((login.clone().split_once("@").unwrap().0.to_owned(), pass_val)); + + let message = MessageBuilder::new() + .from((from.clone(), login.clone())) + .to(vec![(from, login)]) + .subject("StartOS Test Email") + .text_body("This is a test email sent from your StartOS Server"); + client + .connect() + .await + .map_err(|e| Error::new(eyre!("mail-send connection error: {:?}", e), ErrorKind::Unknown))? + .send(message) + .await + .map_err(|e| Error::new(eyre!("mail-send send error: {:?}", e), ErrorKind::Unknown))?; + Ok(()) +} #[tokio::test] #[ignore] From 29e821078254623c2afd01d8b49ddc2d65307ca8 Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Thu, 9 Jan 2025 16:34:34 -0700 Subject: [PATCH 06/35] enabling support for wireguard and firewall (#2713) * wip: enabling support for wireguard and firewall * wip * wip * wip * wip * wip * implement some things * fix warning * wip * alpha.23 * misc fixes * remove ufw since no longer required * remove debug info * add cli bindings * debugging * fixes * individualized acme and privacy settings for domains and bindings * sdk version bump * migration * misc fixes * refactor Host::update * debug info * refactor webserver * misc fixes * misc fixes * refactor port forwarding * recheck interfaces every 5 min if no dbus event * misc fixes and cleanup * misc fixes --- CLEARNET.md | 40 - Makefile | 3 +- build/dpkg-deps/depends | 2 + build/lib/scripts/dhclient-exit-hook | 1 - build/lib/scripts/enable-kiosk | 4 +- .../src/Adapters/EffectCreator.ts | 6 - container-runtime/src/Adapters/RpcListener.ts | 28 +- .../Systems/SystemForEmbassy/index.ts | 1 - .../src/Adapters/Systems/SystemForStartOs.ts | 9 +- core/Cargo.lock | 1149 +++++++++++------ core/models/Cargo.toml | 1 + core/models/src/errors.rs | 7 + core/startos/Cargo.toml | 17 +- core/startos/src/action.rs | 1 - core/startos/src/auth.rs | 3 +- core/startos/src/backup/restore.rs | 3 +- core/startos/src/bins/container_cli.rs | 4 +- core/startos/src/bins/registry.rs | 10 +- core/startos/src/bins/start_cli.rs | 5 +- core/startos/src/bins/start_init.rs | 29 +- core/startos/src/bins/startd.rs | 30 +- core/startos/src/context/config.rs | 16 +- core/startos/src/context/diagnostic.rs | 5 +- core/startos/src/context/rpc.rs | 11 +- core/startos/src/context/setup.rs | 19 +- core/startos/src/db/model/public.rs | 81 +- core/startos/src/diagnostic.rs | 4 +- core/startos/src/disk/mount/backup.rs | 1 - core/startos/src/disk/mount/filesystem/mod.rs | 1 - core/startos/src/init.rs | 29 +- core/startos/src/install/mod.rs | 3 - core/startos/src/lib.rs | 7 +- core/startos/src/lxc/mod.rs | 1 - core/startos/src/net/acme.rs | 174 +-- core/startos/src/net/dhcp.rs | 99 -- core/startos/src/net/forward.rs | 371 ++++-- core/startos/src/net/host/address.rs | 313 ++++- core/startos/src/net/host/binding.rs | 139 +- core/startos/src/net/host/mod.rs | 163 +-- core/startos/src/net/mod.rs | 17 +- core/startos/src/net/net_controller.rs | 554 ++++---- core/startos/src/net/network_interface.rs | 1116 ++++++++++++++++ core/startos/src/net/service_interface.rs | 6 +- core/startos/src/net/ssl.rs | 1 - core/startos/src/net/static_server.rs | 27 +- core/startos/src/net/utils.rs | 61 +- core/startos/src/net/vhost.rs | 1053 ++++++++------- core/startos/src/net/web_server.rs | 335 +++-- core/startos/src/net/wifi.rs | 21 +- core/startos/src/os_install/gpt.rs | 2 +- core/startos/src/prelude.rs | 17 + core/startos/src/registry/context.rs | 1 - core/startos/src/registry/mod.rs | 7 +- core/startos/src/registry/package/index.rs | 1 - .../signer/commitment/merkle_archive.rs | 4 +- core/startos/src/s9pk/git_hash.rs | 29 +- core/startos/src/s9pk/v2/manifest.rs | 5 +- core/startos/src/service/effects/callbacks.rs | 2 +- .../startos/src/service/effects/dependency.rs | 4 +- core/startos/src/service/effects/mod.rs | 4 - core/startos/src/service/effects/net/bind.rs | 37 +- core/startos/src/service/effects/net/host.rs | 25 - .../src/service/effects/net/interface.rs | 3 - core/startos/src/service/effects/net/ssl.rs | 20 +- core/startos/src/service/effects/store.rs | 2 +- core/startos/src/service/mod.rs | 30 +- .../src/service/persistent_container.rs | 10 +- core/startos/src/service/rpc.rs | 2 +- core/startos/src/service/service_actor.rs | 37 +- core/startos/src/service/service_map.rs | 8 +- core/startos/src/service/transition/backup.rs | 3 +- .../startos/src/service/transition/restore.rs | 5 +- core/startos/src/setup.rs | 46 +- core/startos/src/shutdown.rs | 8 +- core/startos/src/status/mod.rs | 2 +- core/startos/src/system.rs | 9 +- core/startos/src/update/mod.rs | 2 +- core/startos/src/util/actor/background.rs | 9 +- core/startos/src/util/future.rs | 62 +- core/startos/src/util/io.rs | 38 +- core/startos/src/util/logger.rs | 68 +- core/startos/src/util/rpc.rs | 1 - core/startos/src/util/rpc_client.rs | 6 +- core/startos/src/util/sync.rs | 1 + core/startos/src/version/mod.rs | 11 +- core/startos/src/version/v0_3_6_alpha_0.rs | 18 +- core/startos/src/version/v0_3_6_alpha_10.rs | 94 ++ core/startos/src/version/v0_3_6_alpha_6.rs | 2 +- core/startos/src/version/v0_3_6_alpha_7.rs | 2 +- core/startos/src/version/v0_3_6_alpha_8.rs | 5 +- core/startos/src/volume.rs | 7 +- debian/postinst | 14 +- image-recipe/build.sh | 4 +- patch-db | 2 +- sdk/base/lib/Effects.ts | 10 +- .../lib/actions/input/builder/inputSpec.ts | 4 +- sdk/base/lib/actions/input/builder/value.ts | 3 + .../lib/dependencies/setupDependencies.ts | 20 +- sdk/base/lib/interfaces/Origin.ts | 2 - .../lib/interfaces/ServiceInterfaceBuilder.ts | 1 - .../{HostAddress.ts => AcmeProvider.ts} | 4 +- sdk/base/lib/osBindings/AcmeSettings.ts | 12 +- sdk/base/lib/osBindings/BindInfo.ts | 4 +- sdk/base/lib/osBindings/DomainConfig.ts | 4 + .../ExportServiceInterfaceParams.ts | 1 - .../lib/osBindings/ForgetInterfaceParams.ts | 3 + .../lib/osBindings/GetPrimaryUrlParams.ts | 10 - sdk/base/lib/osBindings/GitHash.ts | 3 + sdk/base/lib/osBindings/Host.ts | 5 +- sdk/base/lib/osBindings/IpHostname.ts | 8 +- sdk/base/lib/osBindings/IpInfo.ts | 10 +- sdk/base/lib/osBindings/Manifest.ts | 3 +- .../lib/osBindings/{LanInfo.ts => NetInfo.ts} | 3 +- .../lib/osBindings/NetworkInterfaceInfo.ts | 7 + .../lib/osBindings/NetworkInterfaceType.ts | 3 + sdk/base/lib/osBindings/PackageVersionInfo.ts | 3 +- sdk/base/lib/osBindings/ServerInfo.ts | 7 +- sdk/base/lib/osBindings/ServiceInterface.ts | 1 - sdk/base/lib/osBindings/SetPublicParams.ts | 3 + sdk/base/lib/osBindings/UnsetPublicParams.ts | 3 + sdk/base/lib/osBindings/index.ts | 12 +- .../lib/test/startosTypeValidation.test.ts | 2 - sdk/base/lib/types.ts | 27 - sdk/base/lib/util/getServiceInterface.ts | 31 +- sdk/base/lib/util/getServiceInterfaces.ts | 12 - sdk/base/lib/util/patterns.ts | 22 +- sdk/base/package-lock.json | 8 +- sdk/base/package.json | 2 +- sdk/package/lib/StartSdk.ts | 20 +- sdk/package/lib/mainFn/CommandController.ts | 98 +- sdk/package/lib/mainFn/Daemon.ts | 2 + sdk/package/lib/mainFn/Daemons.ts | 59 +- sdk/package/lib/mainFn/HealthDaemon.ts | 13 + sdk/package/lib/manifest/setupManifest.ts | 11 - sdk/package/lib/test/host.test.ts | 1 - sdk/package/package-lock.json | 12 +- sdk/package/package.json | 4 +- web/package-lock.json | 4 +- web/package.json | 2 +- .../app-interfaces/app-interfaces.page.ts | 31 +- .../server-specs/server-specs.page.html | 41 +- .../server-specs/server-specs.page.ts | 1 + .../ui/src/app/services/api/api.fixures.ts | 22 +- .../ui/src/app/services/api/mock-patch.ts | 52 +- 144 files changed, 4878 insertions(+), 2398 deletions(-) delete mode 100644 CLEARNET.md delete mode 100755 build/lib/scripts/dhclient-exit-hook delete mode 100644 core/startos/src/net/dhcp.rs create mode 100644 core/startos/src/net/network_interface.rs create mode 100644 core/startos/src/version/v0_3_6_alpha_10.rs rename sdk/base/lib/osBindings/{HostAddress.ts => AcmeProvider.ts} (51%) create mode 100644 sdk/base/lib/osBindings/DomainConfig.ts create mode 100644 sdk/base/lib/osBindings/ForgetInterfaceParams.ts delete mode 100644 sdk/base/lib/osBindings/GetPrimaryUrlParams.ts create mode 100644 sdk/base/lib/osBindings/GitHash.ts rename sdk/base/lib/osBindings/{LanInfo.ts => NetInfo.ts} (80%) create mode 100644 sdk/base/lib/osBindings/NetworkInterfaceInfo.ts create mode 100644 sdk/base/lib/osBindings/NetworkInterfaceType.ts create mode 100644 sdk/base/lib/osBindings/SetPublicParams.ts create mode 100644 sdk/base/lib/osBindings/UnsetPublicParams.ts diff --git a/CLEARNET.md b/CLEARNET.md deleted file mode 100644 index 457a2e4f7..000000000 --- a/CLEARNET.md +++ /dev/null @@ -1,40 +0,0 @@ -# Setting up clearnet for a service interface - -NOTE: this guide is for HTTPS only! Other configurations may require a more bespoke setup depending on the service. Please consult the service documentation or the Start9 Community for help with non-HTTPS applications - -## Initialize ACME certificate generation - -The following command will register your device with an ACME certificate provider, such as letsencrypt - -This only needs to be done once. - -``` -start-cli net acme init --provider=letsencrypt --contact="mailto:me@drbonez.dev" -``` - -- `provider` can be `letsencrypt`, `letsencrypt-staging` (useful if you're doing a lot of testing and want to avoid being rate limited), or the url of any provider that supports the [RFC8555](https://datatracker.ietf.org/doc/html/rfc8555) ACME api -- `contact` can be any valid contact url, typically `mailto:` urls. it can be specified multiple times to set multiple contacts - -## Whitelist a domain for ACME certificate acquisition - -The following command will tell the OS to use ACME certificates instead of system signed ones for the provided url. In this example, `testing.drbonez.dev` - -This must be done for every domain you wish to host on clearnet. - -``` -start-cli net acme domain add "testing.drbonez.dev" -``` - -## Forward clearnet port - -Go into your router settings, and map port 443 on your router to port 5443 on your start-os device. This one port should cover most use cases - -## Add domain to service host - -The following command will tell the OS to route https requests from the WAN to the provided hostname to the specified service. In this example, we are adding `testing.drbonez.dev` to the host `ui-multi` on the package `hello-world`. To see a list of available host IDs for a given package, run `start-cli package host list` - -This must be done for every domain you wish to host on clearnet. - -``` -start-cli package host hello-world address ui-multi add testing.drbonez.dev -``` diff --git a/Makefile b/Makefile index e0f89f3f9..a00a5c1c9 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ GZIP_BIN := $(shell which pigz || which gzip) TAR_BIN := $(shell which gtar || which tar) COMPILED_TARGETS := core/target/$(ARCH)-unknown-linux-musl/release/startbox core/target/$(ARCH)-unknown-linux-musl/release/containerbox system-images/compat/docker-images/$(ARCH).tar system-images/utils/docker-images/$(ARCH).tar system-images/binfmt/docker-images/$(ARCH).tar container-runtime/rootfs.$(ARCH).squashfs ALL_TARGETS := $(STARTD_SRC) $(ENVIRONMENT_FILE) $(GIT_HASH_FILE) $(VERSION_FILE) $(COMPILED_TARGETS) cargo-deps/$(ARCH)-unknown-linux-musl/release/startos-backup-fs $(shell if [ "$(PLATFORM)" = "raspberrypi" ]; then echo cargo-deps/aarch64-unknown-linux-musl/release/pi-beep; fi) $(shell /bin/bash -c 'if [[ "${ENVIRONMENT}" =~ (^|-)unstable($$|-) ]]; then echo cargo-deps/$(ARCH)-unknown-linux-musl/release/tokio-console; fi') $(PLATFORM_FILE) +REBUILD_TYPES = 1 ifeq ($(REMOTE),) mkdir = mkdir -p $1 @@ -226,7 +227,7 @@ container-runtime/node_modules/.package-lock.json: container-runtime/package.jso npm --prefix container-runtime ci touch container-runtime/node_modules/.package-lock.json -sdk/base/lib/osBindings/index.ts: core/startos/bindings/index.ts +sdk/base/lib/osBindings/index.ts: $(shell if [ "$(REBUILD_TYPES)" -ne 0 ]; then echo core/startos/bindings/index.ts; fi) mkdir -p sdk/base/lib/osBindings rsync -ac --delete core/startos/bindings/ sdk/base/lib/osBindings/ touch sdk/base/lib/osBindings/index.ts diff --git a/build/dpkg-deps/depends b/build/dpkg-deps/depends index f495df85d..4c2dbc557 100644 --- a/build/dpkg-deps/depends +++ b/build/dpkg-deps/depends @@ -11,6 +11,7 @@ cryptsetup curl dnsutils dmidecode +dnsutils dosfstools e2fsprogs ecryptfs-utils @@ -57,4 +58,5 @@ systemd-timesyncd tor util-linux vim +wireguard-tools wireless-tools diff --git a/build/lib/scripts/dhclient-exit-hook b/build/lib/scripts/dhclient-exit-hook deleted file mode 100755 index 8c4a97746..000000000 --- a/build/lib/scripts/dhclient-exit-hook +++ /dev/null @@ -1 +0,0 @@ -start-cli net dhcp update $interface \ No newline at end of file diff --git a/build/lib/scripts/enable-kiosk b/build/lib/scripts/enable-kiosk index 45bed5fe9..cd48fc032 100755 --- a/build/lib/scripts/enable-kiosk +++ b/build/lib/scripts/enable-kiosk @@ -4,7 +4,7 @@ set -e # install dependencies /usr/bin/apt update -/usr/bin/apt install --no-install-recommends -y xserver-xorg x11-xserver-utils xinit firefox-esr matchbox-window-manager libnss3-tools +/usr/bin/apt install --no-install-recommends -y xserver-xorg x11-xserver-utils xinit firefox-esr matchbox-window-manager libnss3-tools p11-kit-modules #Change a default preference set by stock debian firefox-esr sed -i 's|^pref("extensions.update.enabled", true);$|pref("extensions.update.enabled", false);|' /etc/firefox-esr/firefox-esr.js @@ -83,6 +83,8 @@ user_pref("toolkit.telemetry.updatePing.enabled", false); user_pref("toolkit.telemetry.cachedClientID", ""); EOF +ln -sf /usr/lib/$(uname -m)-linux-gnu/pkcs11/p11-kit-trust.so /usr/lib/firefox-esr/libnssckbi.so + # create kiosk script cat > /home/kiosk/kiosk.sh << 'EOF' #!/bin/sh diff --git a/container-runtime/src/Adapters/EffectCreator.ts b/container-runtime/src/Adapters/EffectCreator.ts index 0123b0cbc..4bda0ed5d 100644 --- a/container-runtime/src/Adapters/EffectCreator.ts +++ b/container-runtime/src/Adapters/EffectCreator.ts @@ -216,12 +216,6 @@ export function makeEffects(context: EffectContext): Effects { }) as ReturnType }, - getPrimaryUrl(...[options]: Parameters) { - return rpcRound("get-primary-url", { - ...options, - callback: context.callbacks?.addCallback(options.callback) || null, - }) as ReturnType - }, getServicePortForward( ...[options]: Parameters ) { diff --git a/container-runtime/src/Adapters/RpcListener.ts b/container-runtime/src/Adapters/RpcListener.ts index 3e86e60d1..c2dc8bafe 100644 --- a/container-runtime/src/Adapters/RpcListener.ts +++ b/container-runtime/src/Adapters/RpcListener.ts @@ -212,16 +212,22 @@ export class RpcListener { s.on("data", (a) => Promise.resolve(a) .then((b) => b.toString()) - .then(logData("dataIn")) - .then(jsonParse) - .then(captureId) - .then((x) => this.dealWithInput(x)) - .catch(mapError) - .then(logData("response")) - .then(writeDataToSocket) - .catch((e) => { - console.error(`Major error in socket handling: ${e}`) - console.debug(`Data in: ${a.toString()}`) + .then((buf) => { + for (let s of buf.split("\n")) { + if (s) + Promise.resolve(s) + .then(logData("dataIn")) + .then(jsonParse) + .then(captureId) + .then((x) => this.dealWithInput(x)) + .catch(mapError) + .then(logData("response")) + .then(writeDataToSocket) + .catch((e) => { + console.error(`Major error in socket handling: ${e}`) + console.debug(`Data in: ${a.toString()}`) + }) + } }), ) }) @@ -390,7 +396,7 @@ export class RpcListener { .defaultToLazy(() => { console.warn( - `Coudln't parse the following input ${JSON.stringify(input)}`, + `Couldn't parse the following input ${JSON.stringify(input)}`, ) return { jsonrpc, diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts index 531b30cd2..e74ef317d 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts @@ -425,7 +425,6 @@ export class SystemForEmbassy implements System { name: interfaceValue.name, id: `${id}-${internal}`, description: interfaceValue.description, - hasPrimary: false, type: interfaceValue.ui && (origin.scheme === "http" || origin.sslScheme === "https") diff --git a/container-runtime/src/Adapters/Systems/SystemForStartOs.ts b/container-runtime/src/Adapters/Systems/SystemForStartOs.ts index 334764a87..1d38c83e6 100644 --- a/container-runtime/src/Adapters/Systems/SystemForStartOs.ts +++ b/container-runtime/src/Adapters/Systems/SystemForStartOs.ts @@ -74,8 +74,8 @@ export class SystemForStartOs implements System { async exit(): Promise {} async start(effects: Effects): Promise { + if (this.runningMain) return effects.constRetry = utils.once(() => effects.restart()) - if (this.runningMain) await this.stop() let mainOnTerm: () => Promise | undefined const started = async (onTerm: () => Promise) => { await effects.setMainStatus({ status: "running" }) @@ -98,8 +98,11 @@ export class SystemForStartOs implements System { async stop(): Promise { if (this.runningMain) { - await this.runningMain.stop() - this.runningMain = undefined + try { + await this.runningMain.stop() + } finally { + this.runningMain = undefined + } } } } diff --git a/core/Cargo.lock b/core/Cargo.lock index 48c26ce61..41b912eaf 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -173,9 +173,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "arbitrary" @@ -237,7 +237,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", "synstructure", ] @@ -249,13 +249,13 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "async-acme" -version = "0.5.0" -source = "git+https://github.com/dr-bonez/async-acme.git#b9ff31ad900adc9086c0d1437ce51661d30856d2" +version = "0.6.0" +source = "git+https://github.com/dr-bonez/async-acme.git#0ddf25152237b5fc1726d977a7931e44513ce309" dependencies = [ "async-trait", "base64 0.22.1", @@ -274,6 +274,18 @@ dependencies = [ "x509-parser", ] +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-channel" version = "1.9.0" @@ -281,15 +293,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue 2.5.0", - "event-listener", + "event-listener 2.5.3", "futures-core", ] [[package]] -name = "async-compression" -version = "0.4.17" +name = "async-channel" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb8f1d480b0ea3783ab015936d2a55c87e219676f0c0b7dec61494043f21857" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue 2.5.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-compression" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" dependencies = [ "brotli", "flate2", @@ -299,6 +323,108 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue 2.5.0", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue 2.5.0", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.4.0", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.95", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + [[package]] name = "async-stream" version = "0.3.6" @@ -318,18 +444,24 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] -name = "async-trait" -version = "0.1.83" +name = "async-task" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -355,28 +487,26 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7c2840b66236045acd2607d5866e274380afd87ef99d6226e961e2cb47df45" +checksum = "f409eb70b561706bf8abba8ca9c112729c481595893fd06a2dd9af8ed8441148" dependencies = [ "aws-lc-sys", - "mirai-annotations", "paste", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad3a619a9de81e1d7de1f1186dcba4506ed661a0e483d84410fdef0ee87b2f96" +checksum = "923ded50f602b3007e5e63e3f094c479d9c8a9b42d7f4034e4afe456aa48bfd2" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", - "libc", "paste", ] @@ -393,7 +523,7 @@ dependencies = [ "futures-util", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.31", + "hyper 0.14.32", "itoa", "matchit", "memchr", @@ -419,10 +549,10 @@ dependencies = [ "base64 0.22.1", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "itoa", "matchit", @@ -436,10 +566,10 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", "tokio-tungstenite 0.24.0", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -471,37 +601,18 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", ] -[[package]] -name = "axum-server" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad46c3ec4e12f4a4b6835e173ba21c25e484c9d02b49770bf006ce5367c036" -dependencies = [ - "bytes", - "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.5.1", - "hyper-util", - "pin-project-lite", - "tokio", - "tower 0.4.13", - "tower-service", -] - [[package]] name = "backhand" version = "0.18.0" @@ -540,7 +651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be5951c75bdabb58753d140dd5802f12ff3a483cb2e16fb5276e111b94b19e87" dependencies = [ "concurrent-queue 1.2.4", - "event-listener", + "event-listener 2.5.3", "spin 0.9.8", ] @@ -619,7 +730,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.87", + "syn 2.0.95", "which", ] @@ -629,7 +740,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -638,6 +758,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "1.3.2" @@ -696,9 +822,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec 0.7.6", @@ -727,6 +853,19 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "brotli" version = "7.0.0" @@ -756,9 +895,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.20.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder" @@ -774,9 +913,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "bzip2" @@ -807,9 +946,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cc" -version = "1.2.1" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "jobserver", "libc", @@ -839,9 +978,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -920,9 +1059,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.21" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", "clap_derive", @@ -930,9 +1069,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", @@ -942,27 +1081,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.51" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" dependencies = [ "cc", ] @@ -1020,15 +1159,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.8" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ - "encode_unicode 0.3.6", - "lazy_static", + "encode_unicode", "libc", - "unicode-width 0.1.12", - "windows-sys 0.52.0", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -1077,18 +1216,18 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.31" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.31" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -1163,9 +1302,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -1196,18 +1335,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -1224,18 +1363,18 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -1358,7 +1497,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1382,7 +1521,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1393,7 +1532,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1430,7 +1569,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1467,7 +1606,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1488,7 +1627,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1501,7 +1640,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1554,7 +1693,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -1713,12 +1852,6 @@ dependencies = [ "log", ] -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - [[package]] name = "encode_unicode" version = "1.0.0" @@ -1734,6 +1867,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + [[package]] name = "enum-as-inner" version = "0.6.1" @@ -1743,7 +1882,28 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", +] + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.95", ] [[package]] @@ -1765,12 +1925,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1800,6 +1960,27 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue 2.5.0", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener 5.4.0", + "pin-project-lite", +] + [[package]] name = "exver" version = "0.2.0" @@ -1830,9 +2011,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fd-lock-rs" @@ -1884,7 +2065,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", - "miniz_oxide 0.8.0", + "miniz_oxide 0.8.2", ] [[package]] @@ -2014,6 +2195,19 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-lite" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.31" @@ -2022,7 +2216,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -2085,7 +2279,7 @@ checksum = "75cec8bb4d3d32542cfcb9517f78366b52c17931e30d7ee1682c13686c19cee7" dependencies = [ "futures", "futures-rustls", - "hyper 1.5.1", + "hyper 1.5.2", "log", "serde", "serde_json", @@ -2093,7 +2287,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-rustls 0.25.0", - "webpki-roots 0.26.6", + "webpki-roots 0.26.7", ] [[package]] @@ -2136,9 +2330,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "gpt" @@ -2175,7 +2369,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -2193,8 +2387,8 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.1.0", - "indexmap 2.6.0", + "http 1.2.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -2244,9 +2438,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hashlink" @@ -2397,11 +2591,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2428,9 +2622,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -2455,7 +2649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -2466,7 +2660,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "pin-project-lite", ] @@ -2491,9 +2685,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.31" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", @@ -2515,15 +2709,15 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" dependencies = [ "bytes", "futures-channel", "futures-util", "h2 0.4.7", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "httparse", "httpdate", @@ -2536,18 +2730,18 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.3" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.5.1", + "http 1.2.0", + "hyper 1.5.2", "hyper-util", "rustls 0.23.20", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tower-service", ] @@ -2557,7 +2751,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.31", + "hyper 0.14.32", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -2571,7 +2765,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "native-tls", "tokio", @@ -2588,9 +2782,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", - "hyper 1.5.1", + "hyper 1.5.2", "pin-project-lite", "socket2", "tokio", @@ -2736,7 +2930,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -2812,17 +3006,17 @@ dependencies = [ [[package]] name = "imbl-sized-chunks" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144006fb58ed787dcae3f54575ff4349755b00ccc99f4b4873860b654be1ed63" +checksum = "8f4241005618a62f8d57b2febd02510fb96e0137304728543dfc5fd6f052c22d" dependencies = [ "bitmaps", ] [[package]] name = "imbl-value" -version = "0.1.0" -source = "git+https://github.com/Start9Labs/imbl-value.git#3ce01b17ae5e756fc829ee5e3513a1b19b2a03fc" +version = "0.1.1" +source = "git+https://github.com/Start9Labs/imbl-value.git#1900943e17116def03bf00bff05cf12e54d810bc" dependencies = [ "imbl", "serde", @@ -2869,12 +3063,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] @@ -3016,9 +3210,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jaq-core" @@ -3087,10 +3281,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3141,7 +3336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "ena", "itertools 0.11.0", "lalrpop-util", @@ -3171,7 +3366,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06cf485d4867e0714e35c1652e736bcf892d28fceecca01036764575db64ba84" dependencies = [ - "async-channel", + "async-channel 1.9.0", "futures", ] @@ -3211,15 +3406,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.164" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -3239,7 +3434,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", ] [[package]] @@ -3267,15 +3462,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "litrs" @@ -3389,8 +3584,8 @@ dependencies = [ "rustls-pki-types", "smtp-proto", "tokio", - "tokio-rustls 0.26.0", - "webpki-roots 0.26.6", + "tokio-rustls 0.26.1", + "webpki-roots 0.26.7", ] [[package]] @@ -3476,6 +3671,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -3499,32 +3703,25 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] -[[package]] -name = "mirai-annotations" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" - [[package]] name = "models" version = "0.1.0" @@ -3555,6 +3752,7 @@ dependencies = [ "tracing", "ts-rs", "yasi", + "zbus", ] [[package]] @@ -3625,6 +3823,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", + "memoffset 0.9.1", ] [[package]] @@ -3794,7 +3993,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -3869,7 +4068,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -3900,6 +4099,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "overload" version = "0.1.1" @@ -3950,6 +4159,12 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.3" @@ -3968,7 +4183,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", "smallvec", "windows-targets 0.52.6", ] @@ -4057,20 +4272,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.10", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -4078,22 +4293,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -4107,7 +4322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -4127,29 +4342,29 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -4157,6 +4372,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -4185,10 +4411,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] -name = "portable-atomic" -version = "1.9.0" +name = "polling" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue 2.5.0", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -4213,12 +4454,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -4228,11 +4469,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" dependencies = [ "csv", - "encode_unicode 1.0.0", + "encode_unicode", "is-terminal", "lazy_static", "term", - "unicode-width 0.1.12", + "unicode-width 0.1.14", ] [[package]] @@ -4255,9 +4496,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -4290,12 +4531,12 @@ dependencies = [ [[package]] name = "proptest" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ - "bit-set", - "bit-vec", + "bit-set 0.8.0", + "bit-vec 0.8.0", "bitflags 2.6.0", "lazy_static", "num-traits", @@ -4310,13 +4551,13 @@ dependencies = [ [[package]] name = "proptest-derive" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" +checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -4339,7 +4580,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -4393,9 +4634,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -4540,9 +4781,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -4604,9 +4845,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.9" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ "base64 0.22.1", "bytes", @@ -4616,10 +4857,10 @@ dependencies = [ "futures-core", "futures-util", "h2 0.4.7", - "http 1.1.0", + "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-rustls", "hyper-tls", "hyper-util", @@ -4635,12 +4876,13 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "system-configuration", "tokio", "tokio-native-tls", "tokio-socks", "tokio-util", + "tower 0.5.2", "tower-service", "url", "wasm-bindgen", @@ -4733,7 +4975,7 @@ dependencies = [ "axum 0.7.9", "clap", "futures", - "http 1.1.0", + "http 1.2.0", "http-body-util", "imbl-value", "itertools 0.12.1", @@ -4753,9 +4995,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", "digest 0.10.7", @@ -4825,15 +5067,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags 2.6.0", - "errno 0.3.9", + "errno 0.3.10", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4926,9 +5168,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "rusty-fork" @@ -4944,18 +5186,17 @@ dependencies = [ [[package]] name = "rustyline-async" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9396d834c31f9fddd716e7c279e7cb70207092a1e59767918610f5c560c6eb" +checksum = "6fa3f78c2ea57b827be4c11adbfed26e5fe1b49fb6fb7826e2a9eebbc2e8db10" dependencies = [ "crossterm", - "futures-channel", "futures-util", "pin-project", "thingbuf", - "thiserror 1.0.69", + "thiserror 2.0.10", "unicode-segmentation", - "unicode-width 0.1.12", + "unicode-width 0.2.0", ] [[package]] @@ -5027,9 +5268,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -5037,18 +5278,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.215" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -5072,22 +5313,22 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -5115,6 +5356,17 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.95", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -5138,15 +5390,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", @@ -5156,14 +5408,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -5172,7 +5424,7 @@ version = "0.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ce6afeda22f0b55dde2c34897bce76a629587348480384231205c14b59a01f" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "libyml", "log", @@ -5347,9 +5599,9 @@ checksum = "51b8ad3dd187f0d4debab02ad65405a9919d6a4f7bce25bd64a258781063a53a" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5417,7 +5669,7 @@ dependencies = [ "crc", "crossbeam-queue", "either", - "event-listener", + "event-listener 2.5.3", "futures-channel", "futures-core", "futures-intrusive", @@ -5425,7 +5677,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "memchr", "once_cell", @@ -5593,9 +5845,9 @@ dependencies = [ [[package]] name = "sscanf" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a147d3cf7e723671ed11355b5b008c8019195f7fc902e213f5557d931e9f839d" +checksum = "c713ebd15ce561dd4a13ed62bc2a0368e16806fc30dcaf66ecf1256b2a3fdde6" dependencies = [ "const_format", "lazy_static", @@ -5605,17 +5857,17 @@ dependencies = [ [[package]] name = "sscanf_macro" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a37bdf8e90e77cc60f74473edf28d922ae2eacdd595e67724ccd2381774cc" +checksum = "84955aa74a157e5834d58a07be11af7f0ab923f0194a0bb2ea6b3db8b5d1611d" dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", "regex-syntax 0.6.29", "strsim 0.10.0", - "syn 2.0.87", - "unicode-width 0.1.12", + "syn 2.0.95", + "unicode-width 0.1.14", ] [[package]] @@ -5668,7 +5920,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "start-os" -version = "0.3.6-alpha.9" +version = "0.3.6-alpha.10" dependencies = [ "aes 0.7.5", "async-acme", @@ -5676,7 +5928,6 @@ dependencies = [ "async-stream", "async-trait", "axum 0.7.9", - "axum-server", "backhand", "barrage", "base32 0.5.1", @@ -5691,6 +5942,7 @@ dependencies = [ "color-eyre", "console", "console-subscriber", + "const_format", "cookie", "cookie_store", "der", @@ -5707,14 +5959,15 @@ dependencies = [ "helpers", "hex", "hmac", - "http 1.1.0", + "http 1.2.0", "http-body-util", + "hyper 1.5.2", "hyper-util", "id-pool", "imbl", "imbl-value", "include_dir", - "indexmap 2.6.0", + "indexmap 2.7.0", "indicatif", "integer-encoding", "ipnet", @@ -5732,6 +5985,7 @@ dependencies = [ "log", "mail-send", "mbrman", + "mio", "models", "new_mime_guess", "nix 0.29.0", @@ -5780,7 +6034,7 @@ dependencies = [ "textwrap", "thiserror 1.0.69", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.1", "tokio-socks", "tokio-stream", "tokio-tar", @@ -5802,6 +6056,7 @@ dependencies = [ "url", "urlencoding", "uuid", + "zbus", "zeroize", ] @@ -5866,9 +6121,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -5883,9 +6138,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -5898,7 +6153,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -5936,17 +6191,18 @@ checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" dependencies = [ "filetime", "libc", - "xattr 1.3.1", + "xattr 1.4.0", ] [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom 0.2.15", "once_cell", "rustix", "windows-sys 0.59.0", @@ -5980,7 +6236,7 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width 0.1.12", + "unicode-width 0.1.14", ] [[package]] @@ -6004,11 +6260,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.8" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f5383f3e0071702bf93ab5ee99b52d26936be9dedd9413067cbdcddcb6141a" +checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" dependencies = [ - "thiserror-impl 2.0.8", + "thiserror-impl 2.0.10", ] [[package]] @@ -6019,18 +6275,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "thiserror-impl" -version = "2.0.8" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f357fcec90b3caef6623a099691be676d033b40a058ac95d2a6ade6fa0c943" +checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -6056,9 +6312,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -6077,9 +6333,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -6106,9 +6362,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -6121,9 +6377,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.1" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", @@ -6150,13 +6406,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -6192,12 +6448,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls 0.23.20", - "rustls-pki-types", "tokio", ] @@ -6215,9 +6470,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -6267,9 +6522,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -6317,7 +6572,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -6330,11 +6585,11 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.20", + "winnow 0.6.22", ] [[package]] @@ -6351,7 +6606,7 @@ dependencies = [ "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.31", + "hyper 0.14.32", "hyper-timeout", "percent-encoding", "pin-project", @@ -6405,14 +6660,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.2", "tokio", "tower-layer", "tower-service", @@ -6433,9 +6688,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -6445,20 +6700,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -6466,9 +6721,9 @@ dependencies = [ [[package]] name = "tracing-error" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ "tracing", "tracing-subscriber", @@ -6486,9 +6741,9 @@ dependencies = [ [[package]] name = "tracing-journald" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" +checksum = "fc0b4143302cf1022dac868d521e36e8b27691f72c84b3311750d5188ebba657" dependencies = [ "libc", "tracing-core", @@ -6508,9 +6763,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -6603,7 +6858,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", "termcolor", ] @@ -6627,7 +6882,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", "native-tls", @@ -6647,7 +6902,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", "rand 0.8.5", @@ -6673,7 +6928,7 @@ checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -6688,6 +6943,17 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset 0.9.1", + "tempfile", + "winapi", +] + [[package]] name = "unarray" version = "0.1.4" @@ -6696,21 +6962,21 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-bidi" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-linebreak" @@ -6741,9 +7007,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" @@ -6787,9 +7053,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna 1.0.3", @@ -6902,9 +7168,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -6913,36 +7179,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6950,22 +7216,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-streams" @@ -6982,9 +7248,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -7008,9 +7274,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -7033,7 +7299,7 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", "wasite", ] @@ -7272,9 +7538,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.20" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] @@ -7344,15 +7610,25 @@ dependencies = [ [[package]] name = "xattr" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909" dependencies = [ "libc", "linux-raw-sys", "rustix", ] +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "xz2" version = "0.1.7" @@ -7397,9 +7673,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -7409,16 +7685,79 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", "synstructure", ] +[[package]] +name = "zbus" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb67eadba43784b6fb14857eba0d8fc518686d3ee537066eb6086dc318e2c8a1" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener 5.4.0", + "futures-core", + "futures-util", + "hex", + "nix 0.29.0", + "ordered-stream", + "serde", + "serde_repr", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.59.0", + "winnow 0.6.22", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d49ebc960ceb660f2abe40a5904da975de6986f2af0d7884b39eec6528c57" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.95", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856b7a38811f71846fd47856ceee8bccaec8399ff53fb370247e66081ace647b" +dependencies = [ + "serde", + "static_assertions", + "winnow 0.6.22", + "zvariant", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -7437,27 +7776,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", "synstructure", ] @@ -7478,7 +7817,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -7500,7 +7839,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.95", ] [[package]] @@ -7519,13 +7858,13 @@ dependencies = [ "displaydoc", "flate2", "hmac", - "indexmap 2.6.0", + "indexmap 2.7.0", "lzma-rs", "memchr", "pbkdf2", "rand 0.8.5", "sha1", - "thiserror 2.0.8", + "thiserror 2.0.10", "time", "zeroize", "zopfli", @@ -7573,3 +7912,45 @@ dependencies = [ "cc", "pkg-config", ] + +[[package]] +name = "zvariant" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "winnow 0.6.22", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.95", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "static_assertions", + "syn 2.0.95", + "winnow 0.6.22", +] diff --git a/core/models/Cargo.toml b/core/models/Cargo.toml index f5637c22d..5defd1986 100644 --- a/core/models/Cargo.toml +++ b/core/models/Cargo.toml @@ -40,3 +40,4 @@ tokio = { version = "1", features = ["full"] } torut = { git = "https://github.com/Start9Labs/torut.git", branch = "update/dependencies" } tracing = "0.1.39" yasi = "0.1.5" +zbus = "5" diff --git a/core/models/src/errors.rs b/core/models/src/errors.rs index b57312f05..e7b73b0ec 100644 --- a/core/models/src/errors.rs +++ b/core/models/src/errors.rs @@ -90,6 +90,7 @@ pub enum ErrorKind { Lxc = 72, Cancelled = 73, Git = 74, + DBus = 75, } impl ErrorKind { pub fn as_str(&self) -> &'static str { @@ -169,6 +170,7 @@ impl ErrorKind { Lxc => "LXC Error", Cancelled => "Cancelled", Git => "Git Error", + DBus => "DBus Error", } } } @@ -327,6 +329,11 @@ impl From for Error { Error::new(e, ErrorKind::Tor) } } +impl From for Error { + fn from(e: zbus::Error) -> Self { + Error::new(e, ErrorKind::DBus) + } +} impl From for Error { fn from(e: rustls::Error) -> Self { Error::new(e, ErrorKind::OpenSsl) diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index 0cde21e72..a476db313 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -14,7 +14,7 @@ keywords = [ name = "start-os" readme = "README.md" repository = "https://github.com/Start9Labs/start-os" -version = "0.3.6-alpha.9" +version = "0.3.6-alpha.10" license = "MIT" [lib] @@ -50,7 +50,7 @@ test = [] [dependencies] aes = { version = "0.7.5", features = ["ctr"] } -async-acme = { version = "0.5.0", git = "https://github.com/dr-bonez/async-acme.git", features = [ +async-acme = { version = "0.6.0", git = "https://github.com/dr-bonez/async-acme.git", features = [ "use_rustls", "use_tokio", ] } @@ -62,7 +62,6 @@ async-compression = { version = "0.4.4", features = [ async-stream = "0.3.5" async-trait = "0.1.74" axum = { version = "0.7.3", features = ["ws"] } -axum-server = "0.6.0" barrage = "0.2.3" backhand = "0.18.0" base32 = "0.5.0" @@ -76,6 +75,7 @@ clap = "4.4.12" color-eyre = "0.6.2" console = "0.15.7" console-subscriber = { version = "0.3.0", optional = true } +const_format = "0.2.34" cookie = "0.18.0" cookie_store = "0.21.0" der = { version = "0.7.9", features = ["derive", "pem"] } @@ -102,11 +102,15 @@ hex = "0.4.3" hmac = "0.12.1" http = "1.0.0" http-body-util = "0.1" -hyper-util = { version = "0.1.5", features = [ - "tokio", +hyper = { version = "1.5", features = ["server", "http1", "http2"] } +hyper-util = { version = "0.1.10", features = [ + "server", + "server-auto", + "server-graceful", "service", "http1", "http2", + "tokio", ] } id-pool = { version = "0.2.2", default-features = false, features = [ "serde", @@ -131,12 +135,14 @@ lazy_format = "2.0" lazy_static = "1.4.0" libc = "0.2.149" log = "0.4.20" +mio = "1" mbrman = "0.5.2" models = { version = "*", path = "../models" } new_mime_guess = "4" nix = { version = "0.29.0", features = [ "fs", "mount", + "net", "process", "sched", "signal", @@ -216,6 +222,7 @@ unix-named-pipe = "0.2.0" url = { version = "2.4.1", features = ["serde"] } urlencoding = "2.1.3" uuid = { version = "1.4.1", features = ["v4"] } +zbus = "5.1.1" zeroize = "1.6.0" mail-send = { git = "https://github.com/dr-bonez/mail-send.git", branch = "main" } rustls = "0.23.20" diff --git a/core/startos/src/action.rs b/core/startos/src/action.rs index 801360a44..b29768d73 100644 --- a/core/startos/src/action.rs +++ b/core/startos/src/action.rs @@ -1,4 +1,3 @@ -use std::collections::BTreeMap; use std::fmt; use clap::{CommandFactory, FromArgMatches, Parser}; diff --git a/core/startos/src/auth.rs b/core/startos/src/auth.rs index a6b624b70..9085709ab 100644 --- a/core/startos/src/auth.rs +++ b/core/startos/src/auth.rs @@ -187,9 +187,8 @@ pub fn check_password_against_db(db: &DatabaseModel, password: &str) -> Result<( Ok(()) } -#[derive(Deserialize, Serialize, Parser, TS)] +#[derive(Deserialize, Serialize, TS)] #[serde(rename_all = "camelCase")] -#[command(rename_all = "kebab-case")] #[ts(export)] pub struct LoginParams { password: Option, diff --git a/core/startos/src/backup/restore.rs b/core/startos/src/backup/restore.rs index 28d70653f..e2e9e2158 100644 --- a/core/startos/src/backup/restore.rs +++ b/core/startos/src/backup/restore.rs @@ -109,9 +109,10 @@ pub async fn recover_full_embassy( db.put(&ROOT, &Database::init(&os_backup.account)?).await?; drop(db); - let InitResult { net_ctrl } = init(&ctx.config, init_phases).await?; + let InitResult { net_ctrl } = init(&ctx.webserver, &ctx.config, init_phases).await?; let rpc_ctx = RpcContext::init( + &ctx.webserver, &ctx.config, disk_guid.clone(), Some(net_ctrl), diff --git a/core/startos/src/bins/container_cli.rs b/core/startos/src/bins/container_cli.rs index b0da1cb00..118133f55 100644 --- a/core/startos/src/bins/container_cli.rs +++ b/core/startos/src/bins/container_cli.rs @@ -4,7 +4,7 @@ use rpc_toolkit::CliApp; use serde_json::Value; use crate::service::cli::{ContainerCliContext, ContainerClientConfig}; -use crate::util::logger::EmbassyLogger; +use crate::util::logger::LOGGER; use crate::version::{Current, VersionT}; lazy_static::lazy_static! { @@ -12,7 +12,7 @@ lazy_static::lazy_static! { } pub fn main(args: impl IntoIterator) { - EmbassyLogger::init(); + LOGGER.enable(); if let Err(e) = CliApp::new( |cfg: ContainerClientConfig| Ok(ContainerCliContext::init(cfg)), crate::service::effects::handler(), diff --git a/core/startos/src/bins/registry.rs b/core/startos/src/bins/registry.rs index 132e0984a..9c2cd2b92 100644 --- a/core/startos/src/bins/registry.rs +++ b/core/startos/src/bins/registry.rs @@ -1,20 +1,20 @@ use std::ffi::OsString; use clap::Parser; -use futures::FutureExt; +use futures::{FutureExt}; use tokio::signal::unix::signal; use tracing::instrument; -use crate::net::web_server::WebServer; +use crate::net::web_server::{Acceptor, WebServer}; use crate::prelude::*; use crate::registry::context::{RegistryConfig, RegistryContext}; -use crate::util::logger::EmbassyLogger; +use crate::util::logger::LOGGER; #[instrument(skip_all)] async fn inner_main(config: &RegistryConfig) -> Result<(), Error> { let server = async { let ctx = RegistryContext::init(config).await?; - let mut server = WebServer::new(ctx.listen); + let mut server = WebServer::new(Acceptor::bind([ctx.listen]).await?); server.serve_registry(ctx.clone()); let mut shutdown_recv = ctx.shutdown.subscribe(); @@ -63,7 +63,7 @@ async fn inner_main(config: &RegistryConfig) -> Result<(), Error> { } pub fn main(args: impl IntoIterator) { - EmbassyLogger::init(); + LOGGER.enable(); let config = RegistryConfig::parse_from(args).load().unwrap(); diff --git a/core/startos/src/bins/start_cli.rs b/core/startos/src/bins/start_cli.rs index 2e92e0cc0..bda5e00d3 100644 --- a/core/startos/src/bins/start_cli.rs +++ b/core/startos/src/bins/start_cli.rs @@ -5,7 +5,7 @@ use serde_json::Value; use crate::context::config::ClientConfig; use crate::context::CliContext; -use crate::util::logger::EmbassyLogger; +use crate::util::logger::LOGGER; use crate::version::{Current, VersionT}; lazy_static::lazy_static! { @@ -13,7 +13,8 @@ lazy_static::lazy_static! { } pub fn main(args: impl IntoIterator) { - EmbassyLogger::init(); + LOGGER.enable(); + if let Err(e) = CliApp::new( |cfg: ClientConfig| Ok(CliContext::init(cfg.load()?)?), crate::expanded_api(), diff --git a/core/startos/src/bins/start_init.rs b/core/startos/src/bins/start_init.rs index 394d42c8d..7ff903090 100644 --- a/core/startos/src/bins/start_init.rs +++ b/core/startos/src/bins/start_init.rs @@ -1,3 +1,4 @@ +use std::path::Path; use std::sync::Arc; use tokio::process::Command; @@ -11,16 +12,16 @@ use crate::disk::main::DEFAULT_PASSWORD; use crate::disk::REPAIR_DISK_PATH; use crate::firmware::{check_for_firmware_update, update_firmware}; use crate::init::{InitPhases, InitResult, STANDBY_MODE_PATH}; -use crate::net::web_server::WebServer; +use crate::net::web_server::{UpgradableListener, WebServer}; use crate::prelude::*; use crate::progress::FullProgressTracker; use crate::shutdown::Shutdown; use crate::util::Invoke; -use crate::PLATFORM; +use crate::{DATA_DIR, PLATFORM}; #[instrument(skip_all)] async fn setup_or_init( - server: &mut WebServer, + server: &mut WebServer, config: &ServerConfig, ) -> Result, Error> { if let Some(firmware) = check_for_firmware_update() @@ -111,7 +112,7 @@ async fn setup_or_init( .await .is_err() { - let ctx = SetupContext::init(config)?; + let ctx = SetupContext::init(server, config)?; server.serve_setup(ctx.clone()); @@ -156,7 +157,7 @@ async fn setup_or_init( let disk_guid = Arc::new(String::from(guid_string.trim())); let requires_reboot = crate::disk::main::import( &**disk_guid, - config.datadir(), + DATA_DIR, if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() { RepairStrategy::Aggressive } else { @@ -178,18 +179,26 @@ async fn setup_or_init( tracing::info!("Loaded Disk"); if requires_reboot.0 { + tracing::info!("Rebooting..."); let mut reboot_phase = handle.add_phase("Rebooting".into(), Some(1)); reboot_phase.start(); return Ok(Err(Shutdown { - export_args: Some((disk_guid, config.datadir().to_owned())), + export_args: Some((disk_guid, Path::new(DATA_DIR).to_owned())), restart: true, })); } - let InitResult { net_ctrl } = crate::init::init(config, init_phases).await?; + let InitResult { net_ctrl } = + crate::init::init(&server.acceptor_setter(), config, init_phases).await?; - let rpc_ctx = - RpcContext::init(config, disk_guid, Some(net_ctrl), rpc_ctx_phases).await?; + let rpc_ctx = RpcContext::init( + &server.acceptor_setter(), + config, + disk_guid, + Some(net_ctrl), + rpc_ctx_phases, + ) + .await?; Ok::<_, Error>(Ok((rpc_ctx, handle))) } @@ -203,7 +212,7 @@ async fn setup_or_init( #[instrument(skip_all)] pub async fn main( - server: &mut WebServer, + server: &mut WebServer, config: &ServerConfig, ) -> Result, Error> { if &*PLATFORM == "raspberrypi" && tokio::fs::metadata(STANDBY_MODE_PATH).await.is_ok() { diff --git a/core/startos/src/bins/startd.rs b/core/startos/src/bins/startd.rs index d383f3091..2bf32724e 100644 --- a/core/startos/src/bins/startd.rs +++ b/core/startos/src/bins/startd.rs @@ -1,6 +1,6 @@ use std::cmp::max; use std::ffi::OsString; -use std::net::{Ipv6Addr, SocketAddr}; +use std::net::IpAddr; use std::sync::Arc; use clap::Parser; @@ -12,21 +12,26 @@ use tracing::instrument; use crate::context::config::ServerConfig; use crate::context::rpc::InitRpcContextPhases; use crate::context::{DiagnosticContext, InitContext, RpcContext}; -use crate::net::web_server::WebServer; +use crate::net::utils::ipv6_is_local; +use crate::net::web_server::{Acceptor, UpgradableListener, WebServer}; use crate::shutdown::Shutdown; use crate::system::launch_metrics_task; -use crate::util::logger::EmbassyLogger; +use crate::util::io::append_file; +use crate::util::logger::LOGGER; use crate::{Error, ErrorKind, ResultExt}; #[instrument(skip_all)] async fn inner_main( - server: &mut WebServer, + server: &mut WebServer, config: &ServerConfig, ) -> Result, Error> { let rpc_ctx = if !tokio::fs::metadata("/run/startos/initialized") .await .is_ok() { + LOGGER.set_logfile(Some( + append_file("/run/startos/init.log").await?.into_std().await, + )); let (ctx, handle) = match super::start_init::main(server, &config).await? { Err(s) => return Ok(Some(s)), Ok(ctx) => ctx, @@ -34,6 +39,7 @@ async fn inner_main( tokio::fs::write("/run/startos/initialized", "").await?; server.serve_main(ctx.clone()); + LOGGER.set_logfile(None); handle.complete(); ctx @@ -44,6 +50,7 @@ async fn inner_main( server.serve_init(init_ctx); let ctx = RpcContext::init( + &server.acceptor_setter(), config, Arc::new( tokio::fs::read_to_string("/media/startos/config/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy @@ -131,7 +138,7 @@ async fn inner_main( } pub fn main(args: impl IntoIterator) { - EmbassyLogger::init(); + LOGGER.enable(); let config = ServerConfig::parse_from(args).load().unwrap(); @@ -142,7 +149,18 @@ pub fn main(args: impl IntoIterator) { .build() .expect("failed to initialize runtime"); rt.block_on(async { - let mut server = WebServer::new(SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80)); + let addrs = crate::net::utils::all_socket_addrs_for(80).await?; + let mut server = WebServer::new( + Acceptor::bind_upgradable(addrs.into_iter().filter(|addr| match addr.ip() { + IpAddr::V4(ip4) => { + ip4.is_loopback() + || (ip4.is_private() && !ip4.octets().starts_with(&[10, 59])) // reserving 10.59 for public wireguard configurations + || ip4.is_link_local() + } + IpAddr::V6(ip6) => ipv6_is_local(ip6), + })) + .await?, + ); match inner_main(&mut server, &config).await { Ok(a) => { server.shutdown().await; diff --git a/core/startos/src/context/config.rs b/core/startos/src/context/config.rs index e02648919..3f631c1e4 100644 --- a/core/startos/src/context/config.rs +++ b/core/startos/src/context/config.rs @@ -13,6 +13,7 @@ use crate::disk::OsPartitionInfo; use crate::init::init_postgres; use crate::prelude::*; use crate::util::serde::IoFormat; +use crate::MAIN_DATA; pub const DEVICE_CONFIG_PATH: &str = "/media/startos/config/config.yaml"; // "/media/startos/config/config.yaml"; pub const CONFIG_PATH: &str = "/etc/startos/config.yaml"; @@ -103,8 +104,6 @@ pub struct ServerConfig { #[arg(skip)] pub os_partitions: Option, #[arg(long)] - pub bind_rpc: Option, - #[arg(long)] pub tor_control: Option, #[arg(long)] pub tor_socks: Option, @@ -112,8 +111,6 @@ pub struct ServerConfig { pub dns_bind: Option>, #[arg(long)] pub revision_cache_size: Option, - #[arg(short, long)] - pub datadir: Option, #[arg(long)] pub disable_encryption: Option, #[arg(long)] @@ -126,7 +123,6 @@ impl ContextConfig for ServerConfig { fn merge_with(&mut self, other: Self) { self.ethernet_interface = self.ethernet_interface.take().or(other.ethernet_interface); self.os_partitions = self.os_partitions.take().or(other.os_partitions); - self.bind_rpc = self.bind_rpc.take().or(other.bind_rpc); self.tor_control = self.tor_control.take().or(other.tor_control); self.tor_socks = self.tor_socks.take().or(other.tor_socks); self.dns_bind = self.dns_bind.take().or(other.dns_bind); @@ -134,7 +130,6 @@ impl ContextConfig for ServerConfig { .revision_cache_size .take() .or(other.revision_cache_size); - self.datadir = self.datadir.take().or(other.datadir); self.disable_encryption = self.disable_encryption.take().or(other.disable_encryption); self.multi_arch_s9pks = self.multi_arch_s9pks.take().or(other.multi_arch_s9pks); } @@ -148,13 +143,8 @@ impl ServerConfig { self.load_path_rec(Some(CONFIG_PATH))?; Ok(self) } - pub fn datadir(&self) -> &Path { - self.datadir - .as_deref() - .unwrap_or_else(|| Path::new("/embassy-data")) - } pub async fn db(&self) -> Result { - let db_path = self.datadir().join("main").join("embassy.db"); + let db_path = Path::new(MAIN_DATA).join("embassy.db"); let db = PatchDb::open(&db_path) .await .with_ctx(|_| (crate::ErrorKind::Filesystem, db_path.display().to_string()))?; @@ -163,7 +153,7 @@ impl ServerConfig { } #[instrument(skip_all)] pub async fn secret_store(&self) -> Result { - init_postgres(self.datadir()).await?; + init_postgres("/media/startos/data").await?; let secret_store = PgPool::connect_with(PgConnectOptions::new().database("secrets").username("root")) .await?; diff --git a/core/startos/src/context/diagnostic.rs b/core/startos/src/context/diagnostic.rs index 0bf67e172..6acb21e30 100644 --- a/core/startos/src/context/diagnostic.rs +++ b/core/startos/src/context/diagnostic.rs @@ -1,5 +1,4 @@ use std::ops::Deref; -use std::path::PathBuf; use std::sync::Arc; use rpc_toolkit::yajrc::RpcError; @@ -13,7 +12,6 @@ use crate::shutdown::Shutdown; use crate::Error; pub struct DiagnosticContextSeed { - pub datadir: PathBuf, pub shutdown: Sender, pub error: Arc, pub disk_guid: Option>, @@ -25,7 +23,7 @@ pub struct DiagnosticContext(Arc); impl DiagnosticContext { #[instrument(skip_all)] pub fn init( - config: &ServerConfig, + _config: &ServerConfig, disk_guid: Option>, error: Error, ) -> Result { @@ -35,7 +33,6 @@ impl DiagnosticContext { let (shutdown, _) = tokio::sync::broadcast::channel(1); Ok(Self(Arc::new(DiagnosticContextSeed { - datadir: config.datadir().to_owned(), shutdown, disk_guid, error: Arc::new(error.into()), diff --git a/core/startos/src/context/rpc.rs b/core/startos/src/context/rpc.rs index 73d103adc..a00b9d681 100644 --- a/core/startos/src/context/rpc.rs +++ b/core/startos/src/context/rpc.rs @@ -2,7 +2,6 @@ use std::collections::{BTreeMap, BTreeSet}; use std::future::Future; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::ops::Deref; -use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; @@ -31,6 +30,7 @@ use crate::init::check_time_is_synchronized; use crate::lxc::{ContainerId, LxcContainer, LxcManager}; use crate::net::net_controller::{NetController, PreInitNetController}; use crate::net::utils::{find_eth_iface, find_wifi_iface}; +use crate::net::web_server::{UpgradableListener, WebServerAcceptorSetter}; use crate::net::wifi::WpaCli; use crate::prelude::*; use crate::progress::{FullProgressTracker, PhaseProgressTrackerHandle}; @@ -47,7 +47,6 @@ pub struct RpcContextSeed { pub os_partitions: OsPartitionInfo, pub wifi_interface: Option, pub ethernet_interface: String, - pub datadir: PathBuf, pub disk_guid: Arc, pub ephemeral_sessions: SyncMutex, pub db: TypedPatchDb, @@ -117,6 +116,7 @@ pub struct RpcContext(Arc); impl RpcContext { #[instrument(skip_all)] pub async fn init( + webserver: &WebServerAcceptorSetter, config: &ServerConfig, disk_guid: Arc, net_ctrl: Option, @@ -149,7 +149,7 @@ impl RpcContext { if let Some(net_ctrl) = net_ctrl { net_ctrl } else { - PreInitNetController::init( + let net_ctrl = PreInitNetController::init( db.clone(), config .tor_control @@ -158,7 +158,9 @@ impl RpcContext { &account.hostname, account.tor_key.clone(), ) - .await? + .await?; + webserver.try_upgrade(|a| net_ctrl.net_iface.upgrade_listener(a))?; + net_ctrl }, config .dns_bind @@ -210,7 +212,6 @@ impl RpcContext { let seed = Arc::new(RpcContextSeed { is_closed: AtomicBool::new(false), - datadir: config.datadir().to_path_buf(), os_partitions: config.os_partitions.clone().ok_or_else(|| { Error::new( eyre!("OS Partition Information Missing"), diff --git a/core/startos/src/context/setup.rs b/core/startos/src/context/setup.rs index 96ec07700..30ca1ad39 100644 --- a/core/startos/src/context/setup.rs +++ b/core/startos/src/context/setup.rs @@ -1,5 +1,5 @@ use std::ops::Deref; -use std::path::PathBuf; +use std::path::{Path}; use std::sync::Arc; use std::time::Duration; @@ -10,8 +10,6 @@ use josekit::jwk::Jwk; use patch_db::PatchDb; use rpc_toolkit::Context; use serde::{Deserialize, Serialize}; -use sqlx::postgres::PgConnectOptions; -use sqlx::PgPool; use tokio::sync::broadcast::Sender; use tokio::sync::OnceCell; use tracing::instrument; @@ -22,12 +20,13 @@ use crate::context::config::ServerConfig; use crate::context::RpcContext; use crate::disk::OsPartitionInfo; use crate::hostname::Hostname; -use crate::init::init_postgres; +use crate::net::web_server::{UpgradableListener, WebServer, WebServerAcceptorSetter}; use crate::prelude::*; use crate::progress::FullProgressTracker; use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations}; use crate::setup::SetupProgress; use crate::util::net::WebSocketExt; +use crate::MAIN_DATA; lazy_static::lazy_static! { pub static ref CURRENT_SECRET: Jwk = Jwk::generate_ec_key(josekit::jwk::alg::ec::EcCurve::P256).unwrap_or_else(|e| { @@ -61,6 +60,7 @@ impl TryFrom<&AccountInfo> for SetupResult { } pub struct SetupContextSeed { + pub webserver: WebServerAcceptorSetter, pub config: ServerConfig, pub os_partitions: OsPartitionInfo, pub disable_encryption: bool, @@ -68,7 +68,6 @@ pub struct SetupContextSeed { pub task: OnceCell>, pub result: OnceCell>, pub shutdown: Sender<()>, - pub datadir: PathBuf, pub rpc_continuations: RpcContinuations, } @@ -76,10 +75,13 @@ pub struct SetupContextSeed { pub struct SetupContext(Arc); impl SetupContext { #[instrument(skip_all)] - pub fn init(config: &ServerConfig) -> Result { + pub fn init( + webserver: &WebServer, + config: &ServerConfig, + ) -> Result { let (shutdown, _) = tokio::sync::broadcast::channel(1); - let datadir = config.datadir().to_owned(); Ok(Self(Arc::new(SetupContextSeed { + webserver: webserver.acceptor_setter(), config: config.clone(), os_partitions: config.os_partitions.clone().ok_or_else(|| { Error::new( @@ -92,13 +94,12 @@ impl SetupContext { task: OnceCell::new(), result: OnceCell::new(), shutdown, - datadir, rpc_continuations: RpcContinuations::new(), }))) } #[instrument(skip_all)] pub async fn db(&self) -> Result { - let db_path = self.datadir.join("main").join("embassy.db"); + let db_path = Path::new(MAIN_DATA).join("embassy.db"); let db = PatchDb::open(&db_path) .await .with_ctx(|_| (crate::ErrorKind::Filesystem, db_path.display().to_string()))?; diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index 85978134d..90df469ba 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -1,10 +1,10 @@ use std::collections::{BTreeMap, BTreeSet}; -use std::net::{Ipv4Addr, Ipv6Addr}; +use std::net::{IpAddr, Ipv4Addr}; use chrono::{DateTime, Utc}; use exver::{Version, VersionRange}; use imbl_value::InternedString; -use ipnet::{Ipv4Net, Ipv6Net}; +use ipnet::IpNet; use isocountry::CountryCode; use itertools::Itertools; use models::PackageId; @@ -17,7 +17,7 @@ use ts_rs::TS; use crate::account::AccountInfo; use crate::db::model::package::AllPackageData; -use crate::net::utils::{get_iface_ipv4_addr, get_iface_ipv6_addr}; +use crate::net::acme::AcmeProvider; use crate::prelude::*; use crate::progress::FullProgress; use crate::system::SmtpValue; @@ -54,8 +54,8 @@ impl Public { tor_address: format!("https://{}", account.tor_key.public().get_onion_address()) .parse() .unwrap(), - ip_info: BTreeMap::new(), - acme: None, + network_interfaces: BTreeMap::new(), + acme: BTreeMap::new(), status_info: ServerStatus { backup_progress: None, updated: false, @@ -130,8 +130,11 @@ pub struct ServerInfo { /// for backwards compatibility #[ts(type = "string")] pub tor_address: Url, - pub ip_info: BTreeMap, - pub acme: Option, + #[ts(as = "BTreeMap::")] + #[serde(default)] + pub network_interfaces: BTreeMap, + #[serde(default)] + pub acme: BTreeMap, #[serde(default)] pub status_info: ServerStatus, pub wifi: WifiInfo, @@ -151,43 +154,61 @@ pub struct ServerInfo { pub devices: Vec, } -#[derive(Debug, Deserialize, Serialize, HasModel, TS)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel, TS)] #[serde(rename_all = "camelCase")] #[model = "Model"] #[ts(export)] -pub struct IpInfo { - #[ts(type = "string | null")] - pub ipv4_range: Option, - pub ipv4: Option, - #[ts(type = "string | null")] - pub ipv6_range: Option, - pub ipv6: Option, +pub struct NetworkInterfaceInfo { + pub public: Option, + pub ip_info: Option, } -impl IpInfo { - pub async fn for_interface(iface: &str) -> Result { - let (ipv4, ipv4_range) = get_iface_ipv4_addr(iface).await?.unzip(); - let (ipv6, ipv6_range) = get_iface_ipv6_addr(iface).await?.unzip(); - Ok(Self { - ipv4_range, - ipv4, - ipv6_range, - ipv6, +impl NetworkInterfaceInfo { + pub fn public(&self) -> bool { + self.public.unwrap_or_else(|| { + !self.ip_info.as_ref().map_or(true, |ip_info| { + ip_info.subnets.iter().all(|ipnet| { + match ipnet.addr() { + IpAddr::V4(ip4) => { + ip4.is_loopback() + || (ip4.is_private() && !ip4.octets().starts_with(&[10, 59])) // reserving 10.59 for public wireguard configurations + || ip4.is_link_local() + } + IpAddr::V6(_) => true, + } + }) + }) }) } } +#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize, TS)] +#[ts(export)] +#[serde(rename_all = "camelCase")] +pub struct IpInfo { + pub scope_id: u32, + pub device_type: Option, + #[ts(type = "string[]")] + pub subnets: BTreeSet, + pub wan_ip: Option, + #[ts(type = "string[]")] + pub ntp_servers: BTreeSet, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize, TS)] +#[ts(export)] +#[serde(rename_all = "kebab-case")] +pub enum NetworkInterfaceType { + Ethernet, + Wireless, + Wireguard, +} + #[derive(Debug, Deserialize, Serialize, HasModel, TS)] #[serde(rename_all = "camelCase")] #[model = "Model"] #[ts(export)] pub struct AcmeSettings { - #[ts(type = "string")] - pub provider: Url, - /// email addresses for letsencrypt pub contact: Vec, - #[ts(type = "string[]")] - /// domains to get letsencrypt certs for - pub domains: BTreeSet, } #[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)] diff --git a/core/startos/src/diagnostic.rs b/core/startos/src/diagnostic.rs index f0c142706..73ef93125 100644 --- a/core/startos/src/diagnostic.rs +++ b/core/startos/src/diagnostic.rs @@ -10,7 +10,7 @@ use crate::context::{CliContext, DiagnosticContext, RpcContext}; use crate::init::SYSTEM_REBUILD_PATH; use crate::shutdown::Shutdown; use crate::util::io::delete_file; -use crate::Error; +use crate::{Error, DATA_DIR}; pub fn diagnostic() -> ParentHandler { ParentHandler::new() @@ -71,7 +71,7 @@ pub fn restart(ctx: DiagnosticContext) -> Result<(), Error> { export_args: ctx .disk_guid .clone() - .map(|guid| (guid, ctx.datadir.clone())), + .map(|guid| (guid, Path::new(DATA_DIR).to_owned())), restart: true, }) .expect("receiver dropped"); diff --git a/core/startos/src/disk/mount/backup.rs b/core/startos/src/disk/mount/backup.rs index 2c322c284..3c6f97d91 100644 --- a/core/startos/src/disk/mount/backup.rs +++ b/core/startos/src/disk/mount/backup.rs @@ -7,7 +7,6 @@ use models::PackageId; use tokio::io::AsyncWriteExt; use tracing::instrument; -use super::filesystem::ecryptfs::EcryptFS; use super::guard::{GenericMountGuard, TmpMountGuard}; use crate::auth::check_password; use crate::backup::target::BackupInfo; diff --git a/core/startos/src/disk/mount/filesystem/mod.rs b/core/startos/src/disk/mount/filesystem/mod.rs index 818549a0a..80bfcc903 100644 --- a/core/startos/src/disk/mount/filesystem/mod.rs +++ b/core/startos/src/disk/mount/filesystem/mod.rs @@ -1,7 +1,6 @@ use std::ffi::OsStr; use std::fmt::{Display, Write}; use std::path::Path; -use std::time::Duration; use digest::generic_array::GenericArray; use digest::OutputSizeUser; diff --git a/core/startos/src/init.rs b/core/startos/src/init.rs index a81e7e336..21d23ab5a 100644 --- a/core/startos/src/init.rs +++ b/core/startos/src/init.rs @@ -7,6 +7,7 @@ use std::time::{Duration, SystemTime}; use axum::extract::ws::{self}; use color_eyre::eyre::eyre; +use const_format::formatcp; use futures::{StreamExt, TryStreamExt}; use itertools::Itertools; use models::ResultExt; @@ -25,6 +26,7 @@ use crate::db::model::Database; use crate::disk::mount::util::unmount; use crate::middleware::auth::LOCAL_AUTH_COOKIE_PATH; use crate::net::net_controller::PreInitNetController; +use crate::net::web_server::{UpgradableListener, WebServerAcceptorSetter}; use crate::prelude::*; use crate::progress::{ FullProgress, FullProgressTracker, PhaseProgressTrackerHandle, PhasedProgressBar, @@ -37,7 +39,7 @@ use crate::util::io::{create_file, IOHook}; use crate::util::lshw::lshw; use crate::util::net::WebSocketExt; use crate::util::{cpupower, Invoke}; -use crate::Error; +use crate::{Error, MAIN_DATA, PACKAGE_DATA}; pub const SYSTEM_REBUILD_PATH: &str = "/media/startos/config/system-rebuild"; pub const STANDBY_MODE_PATH: &str = "/media/startos/config/standby"; @@ -274,6 +276,7 @@ pub async fn run_script>(path: P, mut progress: PhaseProgressTrac #[instrument(skip_all)] pub async fn init( + webserver: &WebServerAcceptorSetter, cfg: &ServerConfig, InitPhases { preinit, @@ -317,7 +320,7 @@ pub async fn init( })?; tokio::fs::set_permissions(LOCAL_AUTH_COOKIE_PATH, Permissions::from_mode(0o046)).await?; Command::new("chown") - .arg("root:embassy") + .arg("root:startos") .arg(LOCAL_AUTH_COOKIE_PATH) .invoke(crate::ErrorKind::Filesystem) .await?; @@ -356,10 +359,11 @@ pub async fn init( account.tor_key, ) .await?; + webserver.try_upgrade(|a| net_ctrl.net_iface.upgrade_listener(a))?; start_net.complete(); mount_logs.start(); - let log_dir = cfg.datadir().join("main/logs"); + let log_dir = Path::new(MAIN_DATA).join("logs"); if tokio::fs::metadata(&log_dir).await.is_err() { tokio::fs::create_dir_all(&log_dir).await?; } @@ -419,36 +423,28 @@ pub async fn init( load_ca_cert.complete(); load_wifi.start(); - crate::net::wifi::synchronize_wpa_supplicant_conf( - &cfg.datadir().join("main"), - &mut server_info.wifi, - ) - .await?; + crate::net::wifi::synchronize_network_manager(MAIN_DATA, &mut server_info.wifi).await?; load_wifi.complete(); tracing::info!("Synchronized WiFi"); init_tmp.start(); - let tmp_dir = cfg.datadir().join("package-data/tmp"); + let tmp_dir = Path::new(PACKAGE_DATA).join("tmp"); if tokio::fs::metadata(&tmp_dir).await.is_ok() { tokio::fs::remove_dir_all(&tmp_dir).await?; } if tokio::fs::metadata(&tmp_dir).await.is_err() { tokio::fs::create_dir_all(&tmp_dir).await?; } - let tmp_var = cfg.datadir().join(format!("package-data/tmp/var")); + let tmp_var = Path::new(PACKAGE_DATA).join("tmp/var"); if tokio::fs::metadata(&tmp_var).await.is_ok() { tokio::fs::remove_dir_all(&tmp_var).await?; } crate::disk::mount::util::bind(&tmp_var, "/var/tmp", false).await?; - let downloading = cfg - .datadir() - .join(format!("package-data/archive/downloading")); + let downloading = Path::new(PACKAGE_DATA).join("archive/downloading"); if tokio::fs::metadata(&downloading).await.is_ok() { tokio::fs::remove_dir_all(&downloading).await?; } - let tmp_docker = cfg - .datadir() - .join(format!("package-data/tmp/{CONTAINER_TOOL}")); + let tmp_docker = Path::new(PACKAGE_DATA).join(formatcp!("tmp/{CONTAINER_TOOL}")); crate::disk::mount::util::bind(&tmp_docker, CONTAINER_DATADIR, false).await?; init_tmp.complete(); @@ -509,7 +505,6 @@ pub async fn init( enable_zram.complete(); update_server_info.start(); - server_info.ip_info = crate::net::dhcp::init_ips().await?; server_info.ram = get_mem_info().await?.total.0 as u64 * 1024 * 1024; server_info.devices = lshw().await?; server_info.status_info = ServerStatus { diff --git a/core/startos/src/install/mod.rs b/core/startos/src/install/mod.rs index f153c88ad..bc971da37 100644 --- a/core/startos/src/install/mod.rs +++ b/core/startos/src/install/mod.rs @@ -202,9 +202,6 @@ pub async fn sideload( use axum::extract::ws::Message; async move { if let Err(e) = async { - type RpcResponse = rpc_toolkit::yajrc::RpcResponse< - GenericRpcMethod<&'static str, (), FullProgress>, - >; tokio::select! { res = async { while let Some(progress) = progress_listener.next().await { diff --git a/core/startos/src/lib.rs b/core/startos/src/lib.rs index 8033f5e09..6ab0529c2 100644 --- a/core/startos/src/lib.rs +++ b/core/startos/src/lib.rs @@ -1,6 +1,11 @@ +use const_format::formatcp; + +pub const DATA_DIR: &str = "/media/startos/data"; +pub const MAIN_DATA: &str = formatcp!("{DATA_DIR}/main"); +pub const PACKAGE_DATA: &str = formatcp!("{DATA_DIR}/package-data"); pub const DEFAULT_REGISTRY: &str = "https://registry.start9.com"; // pub const COMMUNITY_MARKETPLACE: &str = "https://community-registry.start9.com"; -pub const HOST_IP: [u8; 4] = [172, 18, 0, 1]; +pub const HOST_IP: [u8; 4] = [10, 0, 3, 1]; pub use std::env::consts::ARCH; lazy_static::lazy_static! { pub static ref PLATFORM: String = { diff --git a/core/startos/src/lxc/mod.rs b/core/startos/src/lxc/mod.rs index 60f9f4301..ce5d28970 100644 --- a/core/startos/src/lxc/mod.rs +++ b/core/startos/src/lxc/mod.rs @@ -1,5 +1,4 @@ use std::collections::BTreeSet; -use std::ffi::OsString; use std::net::Ipv4Addr; use std::path::Path; use std::sync::{Arc, Weak}; diff --git a/core/startos/src/net/acme.rs b/core/startos/src/net/acme.rs index 95f9d4adb..5d8da41f1 100644 --- a/core/startos/src/net/acme.rs +++ b/core/startos/src/net/acme.rs @@ -1,6 +1,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::str::FromStr; +use async_acme::acme::Identifier; use clap::builder::ValueParserFactory; use clap::Parser; use imbl_value::InternedString; @@ -10,6 +11,7 @@ use openssl::pkey::{PKey, Private}; use openssl::x509::X509; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; +use ts_rs::TS; use url::Url; use crate::context::{CliContext, RpcContext}; @@ -78,10 +80,18 @@ impl<'a> async_acme::cache::AcmeCache for AcmeCertCache<'a> { async fn read_certificate( &self, - domains: &[String], + identifiers: &[Identifier], directory_url: &str, ) -> Result, Self::Error> { - let domains = JsonKey::new(domains.into_iter().map(InternedString::intern).collect()); + let identifiers = JsonKey::new( + identifiers + .into_iter() + .map(|d| match d { + Identifier::Dns(d) => d.into(), + Identifier::Ip(ip) => InternedString::from_display(ip), + }) + .collect(), + ); let directory_url = directory_url .parse::() .with_kind(ErrorKind::ParseUrl)?; @@ -94,7 +104,7 @@ impl<'a> async_acme::cache::AcmeCache for AcmeCertCache<'a> { .into_acme() .into_certs() .into_idx(&directory_url) - .and_then(|a| a.into_idx(&domains)) + .and_then(|a| a.into_idx(&identifiers)) else { return Ok(None); }; @@ -120,13 +130,21 @@ impl<'a> async_acme::cache::AcmeCache for AcmeCertCache<'a> { async fn write_certificate( &self, - domains: &[String], + identifiers: &[Identifier], directory_url: &str, key_pem: &str, certificate_pem: &str, ) -> Result<(), Self::Error> { - tracing::info!("Saving new certificate for {domains:?}"); - let domains = JsonKey::new(domains.into_iter().map(InternedString::intern).collect()); + tracing::info!("Saving new certificate for {identifiers:?}"); + let identifiers = JsonKey::new( + identifiers + .into_iter() + .map(|d| match d { + Identifier::Dns(d) => d.into(), + Identifier::Ip(ip) => InternedString::from_display(ip), + }) + .collect(), + ); let directory_url = directory_url .parse::() .with_kind(ErrorKind::ParseUrl)?; @@ -146,7 +164,7 @@ impl<'a> async_acme::cache::AcmeCache for AcmeCertCache<'a> { .as_acme_mut() .as_certs_mut() .upsert(&directory_url, || Ok(BTreeMap::new()))? - .insert(&domains, &cert) + .insert(&identifiers, &cert) }) .await?; @@ -155,22 +173,17 @@ impl<'a> async_acme::cache::AcmeCache for AcmeCertCache<'a> { } pub fn acme() -> ParentHandler { - ParentHandler::new() - .subcommand( - "init", - from_fn_async(init) - .no_display() - .with_about("Setup ACME certificate acquisition") - .with_call_remote::(), - ) - .subcommand( - "domain", - domain::() - .with_about("Add, remove, or view domains for which to acquire ACME certificates"), - ) + ParentHandler::new().subcommand( + "init", + from_fn_async(init) + .no_display() + .with_about("Setup ACME certificate acquisition") + .with_call_remote::(), + ) } -#[derive(Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] +#[ts(type = "string")] pub struct AcmeProvider(pub Url); impl FromStr for AcmeProvider { type Err = ::Err; @@ -183,6 +196,11 @@ impl FromStr for AcmeProvider { .map(Self) } } +impl AsRef for AcmeProvider { + fn as_ref(&self) -> &str { + self.0.as_str() + } +} impl ValueParserFactory for AcmeProvider { type Parser = FromStrParser; fn value_parser() -> Self::Parser { @@ -200,125 +218,15 @@ pub struct InitAcmeParams { pub async fn init( ctx: RpcContext, - InitAcmeParams { - provider: AcmeProvider(provider), - contact, - }: InitAcmeParams, + InitAcmeParams { provider, contact }: InitAcmeParams, ) -> Result<(), Error> { ctx.db .mutate(|db| { db.as_public_mut() .as_server_info_mut() .as_acme_mut() - .map_mutate(|acme| { - Ok(Some(AcmeSettings { - provider, - contact, - domains: acme.map(|acme| acme.domains).unwrap_or_default(), - })) - }) + .insert(&provider, &AcmeSettings { contact }) }) .await?; Ok(()) } - -pub fn domain() -> ParentHandler { - ParentHandler::new() - .subcommand( - "add", - from_fn_async(add_domain) - .no_display() - .with_about("Add a domain for which to acquire ACME certificates") - .with_call_remote::(), - ) - .subcommand( - "remove", - from_fn_async(remove_domain) - .no_display() - .with_about("Remove a domain for which to acquire ACME certificates") - .with_call_remote::(), - ) - .subcommand( - "list", - from_fn_async(list_domains) - .with_custom_display_fn(|_, res| { - for domain in res { - println!("{domain}") - } - Ok(()) - }) - .with_about("List domains for which to acquire ACME certificates") - .with_call_remote::(), - ) -} - -#[derive(Deserialize, Serialize, Parser)] -pub struct DomainParams { - pub domain: InternedString, -} - -pub async fn add_domain( - ctx: RpcContext, - DomainParams { domain }: DomainParams, -) -> Result<(), Error> { - ctx.db - .mutate(|db| { - db.as_public_mut() - .as_server_info_mut() - .as_acme_mut() - .transpose_mut() - .ok_or_else(|| { - Error::new( - eyre!("Please call `start-cli net acme init` before adding a domain"), - ErrorKind::InvalidRequest, - ) - })? - .as_domains_mut() - .mutate(|domains| { - domains.insert(domain); - Ok(()) - }) - }) - .await?; - Ok(()) -} - -pub async fn remove_domain( - ctx: RpcContext, - DomainParams { domain }: DomainParams, -) -> Result<(), Error> { - ctx.db - .mutate(|db| { - if let Some(acme) = db - .as_public_mut() - .as_server_info_mut() - .as_acme_mut() - .transpose_mut() - { - acme.as_domains_mut().mutate(|domains| { - domains.remove(&domain); - Ok(()) - }) - } else { - Ok(()) - } - }) - .await?; - Ok(()) -} - -pub async fn list_domains(ctx: RpcContext) -> Result, Error> { - if let Some(acme) = ctx - .db - .peek() - .await - .into_public() - .into_server_info() - .into_acme() - .transpose() - { - acme.into_domains().de() - } else { - Ok(BTreeSet::new()) - } -} diff --git a/core/startos/src/net/dhcp.rs b/core/startos/src/net/dhcp.rs deleted file mode 100644 index e323ba371..000000000 --- a/core/startos/src/net/dhcp.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::collections::{BTreeMap, BTreeSet}; -use std::net::IpAddr; - -use clap::Parser; -use futures::TryStreamExt; -use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; -use serde::{Deserialize, Serialize}; -use tokio::sync::RwLock; -use ts_rs::TS; - -use crate::context::{CliContext, RpcContext}; -use crate::db::model::public::IpInfo; -use crate::net::utils::{iface_is_physical, list_interfaces}; -use crate::prelude::*; -use crate::Error; - -lazy_static::lazy_static! { - static ref CACHED_IPS: RwLock> = RwLock::new(BTreeSet::new()); -} - -async fn _ips() -> Result, Error> { - Ok(init_ips() - .await? - .values() - .flat_map(|i| { - std::iter::empty() - .chain(i.ipv4.map(IpAddr::from)) - .chain(i.ipv6.map(IpAddr::from)) - }) - .collect()) -} - -pub async fn ips() -> Result, Error> { - let ips = CACHED_IPS.read().await.clone(); - if !ips.is_empty() { - return Ok(ips); - } - let ips = _ips().await?; - *CACHED_IPS.write().await = ips.clone(); - Ok(ips) -} - -pub async fn init_ips() -> Result, Error> { - let mut res = BTreeMap::new(); - let mut ifaces = list_interfaces(); - while let Some(iface) = ifaces.try_next().await? { - if iface_is_physical(&iface).await { - let ip_info = IpInfo::for_interface(&iface).await?; - res.insert(iface, ip_info); - } - } - Ok(res) -} - -// #[command(subcommands(update))] -pub fn dhcp() -> ParentHandler { - ParentHandler::new().subcommand( - "update", - from_fn_async::<_, _, (), Error, (RpcContext, UpdateParams)>(update) - .no_display() - .with_about("Update IP assigned by dhcp") - .with_call_remote::(), - ) -} -#[derive(Deserialize, Serialize, Parser, TS)] -#[serde(rename_all = "camelCase")] -#[command(rename_all = "kebab-case")] -pub struct UpdateParams { - interface: String, -} - -pub async fn update( - ctx: RpcContext, - UpdateParams { interface }: UpdateParams, -) -> Result<(), Error> { - if iface_is_physical(&interface).await { - let ip_info = IpInfo::for_interface(&interface).await?; - ctx.db - .mutate(|db| { - db.as_public_mut() - .as_server_info_mut() - .as_ip_info_mut() - .insert(&interface, &ip_info) - }) - .await?; - - let mut cached = CACHED_IPS.write().await; - if cached.is_empty() { - *cached = _ips().await?; - } else { - cached.extend( - std::iter::empty() - .chain(ip_info.ipv4.map(IpAddr::from)) - .chain(ip_info.ipv6.map(IpAddr::from)), - ); - } - } - Ok(()) -} diff --git a/core/startos/src/net/forward.rs b/core/startos/src/net/forward.rs index e954bc36a..ba62945a0 100644 --- a/core/startos/src/net/forward.rs +++ b/core/startos/src/net/forward.rs @@ -1,12 +1,16 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::net::SocketAddr; use std::sync::{Arc, Weak}; +use futures::channel::oneshot; +use helpers::NonDetachingJoinHandle; use id_pool::IdPool; +use imbl_value::InternedString; use serde::{Deserialize, Serialize}; use tokio::process::Command; -use tokio::sync::Mutex; +use tokio::sync::{mpsc, watch}; +use crate::db::model::public::NetworkInterfaceInfo; use crate::prelude::*; use crate::util::Invoke; @@ -34,144 +38,269 @@ impl AvailablePorts { } } +#[derive(Debug)] +struct ForwardRequest { + public: bool, + target: SocketAddr, + rc: Weak<()>, +} + +#[derive(Debug, Default)] +struct ForwardState { + requested: BTreeMap, + current: BTreeMap>, +} +impl ForwardState { + async fn sync(&mut self, interfaces: &BTreeMap) -> Result<(), Error> { + let private_interfaces = interfaces + .iter() + .filter(|(_, public)| !*public) + .map(|(i, _)| i) + .collect::>(); + let all_interfaces = interfaces.keys().collect::>(); + self.requested.retain(|_, req| req.rc.strong_count() > 0); + for external in self + .requested + .keys() + .chain(self.current.keys()) + .copied() + .collect::>() + { + match ( + self.requested.get(&external), + self.current.get_mut(&external), + ) { + (Some(req), Some(cur)) => { + let expected = if req.public { + &all_interfaces + } else { + &private_interfaces + }; + let actual = cur.keys().collect::>(); + let mut to_rm = actual + .difference(expected) + .copied() + .cloned() + .collect::>(); + let mut to_add = expected + .difference(&actual) + .copied() + .cloned() + .collect::>(); + for interface in actual.intersection(expected).copied() { + if cur[interface] != req.target { + to_rm.insert(interface.clone()); + to_add.insert(interface.clone()); + } + } + for interface in to_rm { + unforward(external, &*interface, cur[&interface]).await?; + cur.remove(&interface); + } + for interface in to_add { + forward(external, &*interface, req.target).await?; + cur.insert(interface, req.target); + } + } + (Some(req), None) => { + let cur = self.current.entry(external).or_default(); + for interface in if req.public { + &all_interfaces + } else { + &private_interfaces + } + .into_iter() + .copied() + .cloned() + { + forward(external, &*interface, req.target).await?; + cur.insert(interface, req.target); + } + } + (None, Some(cur)) => { + let to_rm = cur.keys().cloned().collect::>(); + for interface in to_rm { + unforward(external, &*interface, cur[&interface]).await?; + cur.remove(&interface); + } + self.current.remove(&external); + } + _ => (), + } + } + Ok(()) + } +} + +fn err_has_exited(_: T) -> Error { + Error::new( + eyre!("PortForwardController thread has exited"), + ErrorKind::Unknown, + ) +} + pub struct LanPortForwardController { - forwards: Mutex>>>, + req: mpsc::UnboundedSender<( + Option<(u16, ForwardRequest)>, + oneshot::Sender>, + )>, + _thread: NonDetachingJoinHandle<()>, } impl LanPortForwardController { - pub fn new() -> Self { + pub fn new( + mut net_iface: watch::Receiver>, + ) -> Self { + let (req_send, mut req_recv) = mpsc::unbounded_channel(); + let thread = NonDetachingJoinHandle::from(tokio::spawn(async move { + let mut state = ForwardState::default(); + let mut interfaces = net_iface + .borrow_and_update() + .iter() + .map(|(iface, info)| (iface.clone(), info.public())) + .collect(); + let mut reply: Option>> = None; + loop { + tokio::select! { + msg = req_recv.recv() => { + if let Some((msg, re)) = msg { + if let Some((external, req)) = msg { + state.requested.insert(external, req); + } + reply = Some(re); + } else { + break; + } + } + _ = net_iface.changed() => { + interfaces = net_iface + .borrow() + .iter() + .map(|(iface, info)| (iface.clone(), info.public())) + .collect(); + } + } + let res = state.sync(&interfaces).await; + if let Err(e) = &res { + tracing::error!("Error in PortForwardController: {e}"); + tracing::debug!("{e:?}"); + } + if let Some(re) = reply.take() { + let _ = re.send(res); + } + } + })); Self { - forwards: Mutex::new(BTreeMap::new()), + req: req_send, + _thread: thread, } } - pub async fn add(&self, port: u16, addr: SocketAddr) -> Result, Error> { - let mut writable = self.forwards.lock().await; - let (prev, mut forward) = if let Some(forward) = writable.remove(&port) { - ( - forward.keys().next().cloned(), - forward - .into_iter() - .filter(|(_, rc)| rc.strong_count() > 0) - .collect(), - ) - } else { - (None, BTreeMap::new()) - }; + pub async fn add(&self, port: u16, public: bool, target: SocketAddr) -> Result, Error> { let rc = Arc::new(()); - forward.insert(addr, Arc::downgrade(&rc)); - let next = forward.keys().next().cloned(); - if !forward.is_empty() { - writable.insert(port, forward); - } + let (send, recv) = oneshot::channel(); + self.req + .send(( + Some(( + port, + ForwardRequest { + public, + target, + rc: Arc::downgrade(&rc), + }, + )), + send, + )) + .map_err(err_has_exited)?; - update_forward(port, prev, next).await?; - Ok(rc) + recv.await.map_err(err_has_exited)?.map(|_| rc) } - pub async fn gc(&self, external: u16) -> Result<(), Error> { - let mut writable = self.forwards.lock().await; - let (prev, forward) = if let Some(forward) = writable.remove(&external) { - ( - forward.keys().next().cloned(), - forward - .into_iter() - .filter(|(_, rc)| rc.strong_count() > 0) - .collect(), - ) - } else { - (None, BTreeMap::new()) - }; - let next = forward.keys().next().cloned(); - if !forward.is_empty() { - writable.insert(external, forward); - } + pub async fn gc(&self) -> Result<(), Error> { + let (send, recv) = oneshot::channel(); + self.req.send((None, send)).map_err(err_has_exited)?; - update_forward(external, prev, next).await + recv.await.map_err(err_has_exited)? } } -async fn update_forward( - external: u16, - prev: Option, - next: Option, -) -> Result<(), Error> { - if prev != next { - if let Some(prev) = prev { - unforward(START9_BRIDGE_IFACE, external, prev).await?; - } - if let Some(next) = next { - forward(START9_BRIDGE_IFACE, external, next).await?; - } - } - Ok(()) -} - // iptables -I FORWARD -o br-start9 -p tcp -d 172.18.0.2 --dport 8333 -j ACCEPT // iptables -t nat -I PREROUTING -p tcp --dport 32768 -j DNAT --to 172.18.0.2:8333 -async fn forward(iface: &str, external: u16, addr: SocketAddr) -> Result<(), Error> { - Command::new("iptables") - .arg("-I") - .arg("FORWARD") - .arg("-o") - .arg(iface) - .arg("-p") - .arg("tcp") - .arg("-d") - .arg(addr.ip().to_string()) - .arg("--dport") - .arg(addr.port().to_string()) - .arg("-j") - .arg("ACCEPT") - .invoke(crate::ErrorKind::Network) - .await?; - Command::new("iptables") - .arg("-t") - .arg("nat") - .arg("-I") - .arg("PREROUTING") - .arg("-p") - .arg("tcp") - .arg("--dport") - .arg(external.to_string()) - .arg("-j") - .arg("DNAT") - .arg("--to") - .arg(addr.to_string()) - .invoke(crate::ErrorKind::Network) - .await?; +async fn forward(external: u16, interface: &str, target: SocketAddr) -> Result<(), Error> { + for proto in ["tcp", "udp"] { + Command::new("iptables") + .arg("-I") + .arg("FORWARD") + .arg("-i") + .arg(interface) + .arg("-o") + .arg(START9_BRIDGE_IFACE) + .arg("-p") + .arg(proto) + .arg("-d") + .arg(target.ip().to_string()) + .arg("--dport") + .arg(target.port().to_string()) + .arg("-j") + .arg("ACCEPT") + .invoke(crate::ErrorKind::Network) + .await?; + Command::new("iptables") + .arg("-t") + .arg("nat") + .arg("-I") + .arg("PREROUTING") + .arg("-i") + .arg(interface) + .arg("-p") + .arg(proto) + .arg("--dport") + .arg(external.to_string()) + .arg("-j") + .arg("DNAT") + .arg("--to") + .arg(target.to_string()) + .invoke(crate::ErrorKind::Network) + .await?; + } Ok(()) } // iptables -D FORWARD -o br-start9 -p tcp -d 172.18.0.2 --dport 8333 -j ACCEPT // iptables -t nat -D PREROUTING -p tcp --dport 32768 -j DNAT --to 172.18.0.2:8333 -async fn unforward(iface: &str, external: u16, addr: SocketAddr) -> Result<(), Error> { - Command::new("iptables") - .arg("-D") - .arg("FORWARD") - .arg("-o") - .arg(iface) - .arg("-p") - .arg("tcp") - .arg("-d") - .arg(addr.ip().to_string()) - .arg("--dport") - .arg(addr.port().to_string()) - .arg("-j") - .arg("ACCEPT") - .invoke(crate::ErrorKind::Network) - .await?; - Command::new("iptables") - .arg("-t") - .arg("nat") - .arg("-D") - .arg("PREROUTING") - .arg("-p") - .arg("tcp") - .arg("--dport") - .arg(external.to_string()) - .arg("-j") - .arg("DNAT") - .arg("--to") - .arg(addr.to_string()) - .invoke(crate::ErrorKind::Network) - .await?; +async fn unforward(external: u16, interface: &str, target: SocketAddr) -> Result<(), Error> { + for proto in ["tcp", "udp"] { + Command::new("iptables") + .arg("-D") + .arg("FORWARD") + .arg("-i") + .arg(interface) + .arg("-o") + .arg(START9_BRIDGE_IFACE) + .arg("-p") + .arg(proto) + .arg("-d") + .arg(target.ip().to_string()) + .arg("--dport") + .arg(target.port().to_string()) + .arg("-j") + .arg("ACCEPT") + .invoke(crate::ErrorKind::Network) + .await?; + Command::new("iptables") + .arg("-t") + .arg("nat") + .arg("-D") + .arg("PREROUTING") + .arg("-i") + .arg(interface) + .arg("-p") + .arg(proto) + .arg("--dport") + .arg(external.to_string()) + .arg("-j") + .arg("DNAT") + .arg("--to") + .arg(target.to_string()) + .invoke(crate::ErrorKind::Network) + .await?; + } Ok(()) } diff --git a/core/startos/src/net/host/address.rs b/core/startos/src/net/host/address.rs index 05942ffa9..3d639b31e 100644 --- a/core/startos/src/net/host/address.rs +++ b/core/startos/src/net/host/address.rs @@ -1,57 +1,298 @@ -use std::fmt; -use std::str::FromStr; - -use clap::builder::ValueParserFactory; +use clap::Parser; use imbl_value::InternedString; -use models::FromStrParser; +use models::{HostId, PackageId}; +use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; use torut::onion::OnionAddressV3; use ts_rs::TS; +use crate::context::{CliContext, RpcContext}; +use crate::net::acme::AcmeProvider; use crate::prelude::*; +use crate::util::serde::{display_serializable, HandlerExtSerde}; -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, TS)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "kind")] -#[ts(export)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum HostAddress { Onion { - #[ts(type = "string")] address: OnionAddressV3, }, Domain { - #[ts(type = "string")] address: InternedString, + public: bool, + acme: Option, }, } -impl FromStr for HostAddress { - type Err = Error; - fn from_str(s: &str) -> Result { - if let Some(addr) = s.strip_suffix(".onion") { - Ok(HostAddress::Onion { - address: addr - .parse::() - .with_kind(ErrorKind::ParseUrl)?, - }) - } else { - Ok(HostAddress::Domain { address: s.into() }) - } - } +#[derive(Debug, Deserialize, Serialize, TS)] +pub struct DomainConfig { + pub public: bool, + pub acme: Option, } -impl fmt::Display for HostAddress { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Onion { address } => write!(f, "{address}"), - Self::Domain { address } => write!(f, "{address}"), - } - } +#[derive(Deserialize, Serialize, Parser)] +pub struct AddressApiParams { + host: HostId, } -impl ValueParserFactory for HostAddress { - type Parser = FromStrParser; - fn value_parser() -> Self::Parser { - Self::Parser::new() - } +pub fn address() -> ParentHandler { + ParentHandler::::new() + .subcommand( + "domain", + ParentHandler::::new() + .subcommand( + "add", + from_fn_async(add_domain) + .with_inherited(|_, a| a) + .no_display() + .with_about("Add an address to this host") + .with_call_remote::(), + ) + .subcommand( + "remove", + from_fn_async(remove_domain) + .with_inherited(|_, a| a) + .no_display() + .with_about("Remove an address from this host") + .with_call_remote::(), + ) + .with_inherited(|AddressApiParams { host }, package| (package, host)), + ) + .subcommand( + "onion", + ParentHandler::::new() + .subcommand( + "add", + from_fn_async(add_onion) + .with_inherited(|_, a| a) + .no_display() + .with_about("Add an address to this host") + .with_call_remote::(), + ) + .subcommand( + "remove", + from_fn_async(remove_onion) + .with_inherited(|_, a| a) + .no_display() + .with_about("Remove an address from this host") + .with_call_remote::(), + ) + .with_inherited(|AddressApiParams { host }, package| (package, host)), + ) + .subcommand( + "list", + from_fn_async(list_addresses) + .with_inherited(|AddressApiParams { host }, package| (package, host)) + .with_display_serializable() + .with_custom_display_fn(|HandlerArgs { params, .. }, res| { + use prettytable::*; + + if let Some(format) = params.format { + display_serializable(format, res); + return Ok(()); + } + + let mut table = Table::new(); + table.add_row(row![bc => "ADDRESS", "PUBLIC", "ACME PROVIDER"]); + for address in &res { + match address { + HostAddress::Onion { address } => { + table.add_row(row![address, true, "N/A"]); + } + HostAddress::Domain { + address, + public, + acme, + } => { + table.add_row(row![ + address, + *public, + acme.as_ref().map(|a| a.0.as_str()).unwrap_or("NONE") + ]); + } + } + } + + table.print_tty(false)?; + + Ok(()) + }) + .with_about("List addresses for this host") + .with_call_remote::(), + ) +} + +#[derive(Deserialize, Serialize, Parser)] +pub struct AddDomainParams { + pub domain: InternedString, + #[arg(long)] + pub private: bool, + #[arg(long)] + pub acme: Option, +} + +pub async fn add_domain( + ctx: RpcContext, + AddDomainParams { + domain, + private, + acme, + }: AddDomainParams, + (package, host): (PackageId, HostId), +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + if let Some(acme) = &acme { + if !db.as_public().as_server_info().as_acme().contains_key(&acme)? { + return Err(Error::new(eyre!("unknown acme provider {}, please run acme.init for this provider first", acme.0), ErrorKind::InvalidRequest)); + } + } + + db.as_public_mut() + .as_package_data_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_hosts_mut() + .as_idx_mut(&host) + .or_not_found(&host)? + .as_domains_mut() + .insert( + &domain, + &DomainConfig { + public: !private, + acme, + }, + ) + }) + .await?; + let service = ctx.services.get(&package).await; + let service_ref = service.as_ref().or_not_found(&package)?; + service_ref.update_host(host).await?; + + Ok(()) +} + +#[derive(Deserialize, Serialize, Parser)] +pub struct RemoveDomainParams { + pub domain: InternedString, +} + +pub async fn remove_domain( + ctx: RpcContext, + RemoveDomainParams { domain }: RemoveDomainParams, + (package, host): (PackageId, HostId), +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + db.as_public_mut() + .as_package_data_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_hosts_mut() + .as_idx_mut(&host) + .or_not_found(&host)? + .as_domains_mut() + .remove(&domain) + }) + .await?; + let service = ctx.services.get(&package).await; + let service_ref = service.as_ref().or_not_found(&package)?; + service_ref.update_host(host).await?; + + Ok(()) +} + +#[derive(Deserialize, Serialize, Parser)] +pub struct OnionParams { + pub onion: String, +} + +pub async fn add_onion( + ctx: RpcContext, + OnionParams { onion }: OnionParams, + (package, host): (PackageId, HostId), +) -> Result<(), Error> { + let onion = onion + .strip_suffix(".onion") + .ok_or_else(|| { + Error::new( + eyre!("onion hostname must end in .onion"), + ErrorKind::InvalidOnionAddress, + ) + })? + .parse::()?; + ctx.db + .mutate(|db| { + db.as_private().as_key_store().as_onion().get_key(&onion)?; + + db.as_public_mut() + .as_package_data_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_hosts_mut() + .as_idx_mut(&host) + .or_not_found(&host)? + .as_onions_mut() + .mutate(|a| Ok(a.insert(onion))) + }) + .await?; + let service = ctx.services.get(&package).await; + let service_ref = service.as_ref().or_not_found(&package)?; + service_ref.update_host(host).await?; + + Ok(()) +} + +pub async fn remove_onion( + ctx: RpcContext, + OnionParams { onion }: OnionParams, + (package, host): (PackageId, HostId), +) -> Result<(), Error> { + let onion = onion + .strip_suffix(".onion") + .ok_or_else(|| { + Error::new( + eyre!("onion hostname must end in .onion"), + ErrorKind::InvalidOnionAddress, + ) + })? + .parse::()?; + ctx.db + .mutate(|db| { + db.as_public_mut() + .as_package_data_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_hosts_mut() + .as_idx_mut(&host) + .or_not_found(&host)? + .as_onions_mut() + .mutate(|a| Ok(a.remove(&onion))) + }) + .await?; + let service = ctx.services.get(&package).await; + let service_ref = service.as_ref().or_not_found(&package)?; + service_ref.update_host(host).await?; + + Ok(()) +} + +pub async fn list_addresses( + ctx: RpcContext, + _: Empty, + (package, host): (PackageId, HostId), +) -> Result, Error> { + Ok(ctx + .db + .peek() + .await + .into_public() + .into_package_data() + .into_idx(&package) + .or_not_found(&package)? + .into_hosts() + .into_idx(&host) + .or_not_found(&host)? + .de()? + .addresses() + .collect()) } diff --git a/core/startos/src/net/host/binding.rs b/core/startos/src/net/host/binding.rs index 174f0330f..d56f607a9 100644 --- a/core/startos/src/net/host/binding.rs +++ b/core/startos/src/net/host/binding.rs @@ -1,13 +1,18 @@ +use std::collections::BTreeMap; use std::str::FromStr; use clap::builder::ValueParserFactory; -use models::{FromStrParser, HostId}; +use clap::Parser; +use models::{FromStrParser, HostId, PackageId}; +use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; use ts_rs::TS; +use crate::context::{CliContext, RpcContext}; use crate::net::forward::AvailablePorts; use crate::net::vhost::AlpnInfo; use crate::prelude::*; +use crate::util::serde::{display_serializable, HandlerExtSerde}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)] #[ts(export)] @@ -41,12 +46,14 @@ impl FromStr for BindId { pub struct BindInfo { pub enabled: bool, pub options: BindOptions, - pub lan: LanInfo, + pub net: NetInfo, } + #[derive(Clone, Copy, Debug, Deserialize, Serialize, TS, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "camelCase")] #[ts(export)] -pub struct LanInfo { +pub struct NetInfo { + pub public: bool, pub assigned_port: Option, pub assigned_ssl_port: Option, } @@ -63,7 +70,8 @@ impl BindInfo { Ok(Self { enabled: true, options, - lan: LanInfo { + net: NetInfo { + public: false, assigned_port, assigned_ssl_port, }, @@ -74,7 +82,7 @@ impl BindInfo { available_ports: &mut AvailablePorts, options: BindOptions, ) -> Result { - let Self { mut lan, .. } = self; + let Self { net: mut lan, .. } = self; if options .secure .map_or(false, |s| !(s.ssl && options.add_ssl.is_some())) @@ -104,7 +112,7 @@ impl BindInfo { Ok(Self { enabled: true, options, - lan, + net: lan, }) } pub fn disable(&mut self) { @@ -137,3 +145,122 @@ pub struct AddSslOptions { // pub add_x_forwarded_headers: bool, // TODO pub alpn: Option, } + +#[derive(Deserialize, Serialize, Parser)] +pub struct BindingApiParams { + host: HostId, +} + +pub fn binding() -> ParentHandler { + ParentHandler::::new() + .subcommand( + "list", + from_fn_async(list_bindings) + .with_inherited(|BindingApiParams { host }, package| (package, host)) + .with_display_serializable() + .with_custom_display_fn(|HandlerArgs { params, .. }, res| { + use prettytable::*; + + if let Some(format) = params.format { + return Ok(display_serializable(format, res)); + } + + let mut table = Table::new(); + table.add_row(row![bc => "INTERNAL PORT", "ENABLED", "PUBLIC", "EXTERNAL PORT", "EXTERNAL SSL PORT"]); + for (internal, info) in res { + table.add_row(row![ + internal, + info.enabled, + info.net.public, + if let Some(port) = info.net.assigned_port { + port.to_string() + } else { + "N/A".to_owned() + }, + if let Some(port) = info.net.assigned_ssl_port { + port.to_string() + } else { + "N/A".to_owned() + }, + ]); + } + + table.print_tty(false).unwrap(); + + Ok(()) + }) + .with_about("List bindinges for this host") + .with_call_remote::(), + ) + .subcommand( + "set-public", + from_fn_async(set_public) + .with_inherited(|BindingApiParams { host }, package| (package, host)) + .no_display() + .with_about("Add an binding to this host") + .with_call_remote::(), + ) +} + +pub async fn list_bindings( + ctx: RpcContext, + _: Empty, + (package, host): (PackageId, HostId), +) -> Result, Error> { + ctx.db + .peek() + .await + .into_public() + .into_package_data() + .into_idx(&package) + .or_not_found(&package)? + .into_hosts() + .into_idx(&host) + .or_not_found(&host)? + .into_bindings() + .de() +} + +#[derive(Deserialize, Serialize, Parser)] +#[serde(rename_all = "camelCase")] +pub struct SetPublicParams { + internal_port: u16, + #[arg(long)] + public: Option, +} + +pub async fn set_public( + ctx: RpcContext, + SetPublicParams { + internal_port, + public, + }: SetPublicParams, + (package, host): (PackageId, HostId), +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + db.as_public_mut() + .as_package_data_mut() + .as_idx_mut(&package) + .or_not_found(&package)? + .as_hosts_mut() + .as_idx_mut(&host) + .or_not_found(&host)? + .as_bindings_mut() + .mutate(|b| { + b.get_mut(&internal_port) + .or_not_found(internal_port)? + .net + .public = public.unwrap_or(true); + Ok(()) + }) + }) + .await?; + ctx.services + .get(&package) + .await + .as_ref() + .or_not_found(&package)? + .update_host(host) + .await +} diff --git a/core/startos/src/net/host/mod.rs b/core/startos/src/net/host/mod.rs index be5db0f2d..9f4194866 100644 --- a/core/startos/src/net/host/mod.rs +++ b/core/startos/src/net/host/mod.rs @@ -5,13 +5,14 @@ use imbl_value::InternedString; use models::{HostId, PackageId}; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; +use torut::onion::OnionAddressV3; use ts_rs::TS; -use crate::context::{CliContext, RpcContext}; +use crate::context::RpcContext; use crate::db::model::DatabaseModel; use crate::net::forward::AvailablePorts; -use crate::net::host::address::HostAddress; -use crate::net::host::binding::{BindInfo, BindOptions}; +use crate::net::host::address::{address, DomainConfig, HostAddress}; +use crate::net::host::binding::{binding, BindInfo, BindOptions}; use crate::net::service_interface::HostnameInfo; use crate::prelude::*; @@ -25,7 +26,10 @@ pub mod binding; pub struct Host { pub kind: HostKind, pub bindings: BTreeMap, - pub addresses: BTreeSet, + #[ts(type = "string[]")] + pub onions: BTreeSet, + #[ts(as = "BTreeMap::")] + pub domains: BTreeMap, /// COMPUTED: NetService::update pub hostname_info: BTreeMap>, // internal port -> Hostnames } @@ -39,13 +43,27 @@ impl Host { Self { kind, bindings: BTreeMap::new(), - addresses: BTreeSet::new(), + onions: BTreeSet::new(), + domains: BTreeMap::new(), hostname_info: BTreeMap::new(), } } - pub fn addresses(&self) -> impl Iterator { - // TODO: handle primary - self.addresses.iter() + pub fn addresses<'a>(&'a self) -> impl Iterator + 'a { + self.onions + .iter() + .cloned() + .map(|address| HostAddress::Onion { address }) + .chain( + self.domains + .iter() + .map( + |(address, DomainConfig { public, acme })| HostAddress::Domain { + address: address.clone(), + public: *public, + acme: acme.clone(), + }, + ), + ) } } @@ -104,12 +122,12 @@ pub fn host_for<'a>( }; host_info(db, package_id)?.upsert(host_id, || { let mut h = Host::new(host_kind); - h.addresses.insert(HostAddress::Onion { - address: tor_key + h.onions.insert( + tor_key .or_not_found("generated tor key")? .public() .get_onion_address(), - }); + ); Ok(h) }) } @@ -161,6 +179,10 @@ pub fn host() -> ParentHandler { "address", address::().with_inherited(|HostParams { package }, _| package), ) + .subcommand( + "binding", + binding::().with_inherited(|HostParams { package }, _| package), + ) } pub async fn list_hosts( @@ -178,122 +200,3 @@ pub async fn list_hosts( .into_hosts() .keys() } - -#[derive(Deserialize, Serialize, Parser)] -pub struct AddressApiParams { - host: HostId, -} - -pub fn address() -> ParentHandler { - ParentHandler::::new() - .subcommand( - "add", - from_fn_async(add_address) - .with_inherited(|AddressApiParams { host }, package| (package, host)) - .no_display() - .with_about("Add an address to this host") - .with_call_remote::(), - ) - .subcommand( - "remove", - from_fn_async(remove_address) - .with_inherited(|AddressApiParams { host }, package| (package, host)) - .no_display() - .with_about("Remove an address from this host") - .with_call_remote::(), - ) - .subcommand( - "list", - from_fn_async(list_addresses) - .with_inherited(|AddressApiParams { host }, package| (package, host)) - .with_custom_display_fn(|_, res| { - for address in res { - println!("{address}") - } - Ok(()) - }) - .with_about("List addresses for this host") - .with_call_remote::(), - ) -} - -#[derive(Deserialize, Serialize, Parser)] -pub struct AddressParams { - pub address: HostAddress, -} - -pub async fn add_address( - ctx: RpcContext, - AddressParams { address }: AddressParams, - (package, host): (PackageId, HostId), -) -> Result<(), Error> { - ctx.db - .mutate(|db| { - if let HostAddress::Onion { address } = address { - db.as_private() - .as_key_store() - .as_onion() - .get_key(&address)?; - } - - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? - .as_addresses_mut() - .mutate(|a| Ok(a.insert(address))) - }) - .await?; - let service = ctx.services.get(&package).await; - let service_ref = service.as_ref().or_not_found(&package)?; - service_ref.update_host(host).await?; - - Ok(()) -} - -pub async fn remove_address( - ctx: RpcContext, - AddressParams { address }: AddressParams, - (package, host): (PackageId, HostId), -) -> Result<(), Error> { - ctx.db - .mutate(|db| { - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? - .as_addresses_mut() - .mutate(|a| Ok(a.remove(&address))) - }) - .await?; - let service = ctx.services.get(&package).await; - let service_ref = service.as_ref().or_not_found(&package)?; - service_ref.update_host(host).await?; - - Ok(()) -} - -pub async fn list_addresses( - ctx: RpcContext, - _: Empty, - (package, host): (PackageId, HostId), -) -> Result, Error> { - ctx.db - .peek() - .await - .into_public() - .into_package_data() - .into_idx(&package) - .or_not_found(&package)? - .into_hosts() - .into_idx(&host) - .or_not_found(&host)? - .into_addresses() - .de() -} diff --git a/core/startos/src/net/mod.rs b/core/startos/src/net/mod.rs index 53b94454d..49d3560ef 100644 --- a/core/startos/src/net/mod.rs +++ b/core/startos/src/net/mod.rs @@ -1,13 +1,13 @@ use rpc_toolkit::{Context, HandlerExt, ParentHandler}; pub mod acme; -pub mod dhcp; pub mod dns; pub mod forward; pub mod host; pub mod keys; pub mod mdns; pub mod net_controller; +pub mod network_interface; pub mod service_interface; pub mod ssl; pub mod static_server; @@ -17,20 +17,23 @@ pub mod vhost; pub mod web_server; pub mod wifi; -pub const PACKAGE_CERT_PATH: &str = "/var/lib/embassy/ssl"; - pub fn net() -> ParentHandler { ParentHandler::new() .subcommand( "tor", tor::tor::().with_about("Tor commands such as list-services, logs, and reset"), ) - .subcommand( - "dhcp", - dhcp::dhcp::().with_about("Command to update IP assigned from dhcp"), - ) .subcommand( "acme", acme::acme::().with_about("Setup automatic clearnet certificate acquisition"), ) + .subcommand( + "network-interface", + network_interface::network_interface_api::() + .with_about("View and edit network interface configurations"), + ) + .subcommand( + "vhost", + vhost::vhost_api::().with_about("Manage ssl virtual host proxy"), + ) } diff --git a/core/startos/src/net/net_controller.rs b/core/startos/src/net/net_controller.rs index a8beaf55f..7ff707fbe 100644 --- a/core/startos/src/net/net_controller.rs +++ b/core/startos/src/net/net_controller.rs @@ -5,6 +5,7 @@ use std::sync::{Arc, Weak}; use color_eyre::eyre::eyre; use imbl::OrdMap; use imbl_value::InternedString; +use ipnet::IpNet; use models::{HostId, OptionExt, PackageId}; use torut::onion::{OnionAddressV3, TorSecretKeyV3}; use tracing::instrument; @@ -15,11 +16,13 @@ use crate::hostname::Hostname; use crate::net::dns::DnsController; use crate::net::forward::LanPortForwardController; use crate::net::host::address::HostAddress; -use crate::net::host::binding::{AddSslOptions, BindId, BindOptions, LanInfo}; +use crate::net::host::binding::{BindId, BindOptions}; use crate::net::host::{host_for, Host, HostKind, Hosts}; +use crate::net::network_interface::NetworkInterfaceController; use crate::net::service_interface::{HostnameInfo, IpHostname, OnionHostname}; use crate::net::tor::TorController; -use crate::net::vhost::{AlpnInfo, VHostController}; +use crate::net::utils::ipv6_is_local; +use crate::net::vhost::{AlpnInfo, TargetInfo, VHostController}; use crate::prelude::*; use crate::util::serde::MaybeUtf8String; use crate::HOST_IP; @@ -28,6 +31,7 @@ pub struct PreInitNetController { pub db: TypedPatchDb, tor: TorController, vhost: VHostController, + pub net_iface: Arc, os_bindings: Vec>, server_hostnames: Vec>, } @@ -40,10 +44,12 @@ impl PreInitNetController { hostname: &Hostname, os_tor_key: TorSecretKeyV3, ) -> Result { + let net_iface = Arc::new(NetworkInterfaceController::new(db.clone())); let mut res = Self { db: db.clone(), tor: TorController::new(tor_control, tor_socks), - vhost: VHostController::new(db), + vhost: VHostController::new(db, net_iface.clone()), + net_iface, os_bindings: Vec::new(), server_hostnames: Vec::new(), }; @@ -56,11 +62,6 @@ impl PreInitNetController { hostname: &Hostname, tor_key: TorSecretKeyV3, ) -> Result<(), Error> { - let alpn = Err(AlpnInfo::Specified(vec![ - MaybeUtf8String("http/1.1".into()), - MaybeUtf8String("h2".into()), - ])); - self.server_hostnames = vec![ // LAN IP None, @@ -74,27 +75,29 @@ impl PreInitNetController { Some(hostname.local_domain_name()), ]; + let vhost_target = TargetInfo { + public: false, + acme: None, + addr: ([127, 0, 0, 1], 80).into(), + connect_ssl: Err(AlpnInfo::Specified(vec![ + MaybeUtf8String("http/1.1".into()), + MaybeUtf8String("h2".into()), + ])), + }; + for hostname in self.server_hostnames.iter().cloned() { - self.os_bindings.push( - self.vhost - .add(hostname, 443, ([127, 0, 0, 1], 80).into(), alpn.clone()) - .await?, - ); + self.os_bindings + .push(self.vhost.add(hostname, 443, vhost_target.clone())?); } // Tor - self.os_bindings.push( - self.vhost - .add( - Some(InternedString::from_display( - &tor_key.public().get_onion_address(), - )), - 443, - ([127, 0, 0, 1], 80).into(), - alpn.clone(), - ) - .await?, - ); + self.os_bindings.push(self.vhost.add( + Some(InternedString::from_display( + &tor_key.public().get_onion_address(), + )), + 443, + vhost_target, + )?); self.os_bindings.extend( self.tor .add( @@ -115,6 +118,7 @@ pub struct NetController { db: TypedPatchDb, pub(super) tor: TorController, pub(super) vhost: VHostController, + pub net_iface: Arc, pub(super) dns: DnsController, pub(super) forward: LanPortForwardController, pub(super) os_bindings: Vec>, @@ -127,6 +131,7 @@ impl NetController { db, tor, vhost, + net_iface, os_bindings, server_hostnames, }: PreInitNetController, @@ -137,7 +142,8 @@ impl NetController { tor, vhost, dns: DnsController::init(dns_bind).await?, - forward: LanPortForwardController::new(), + forward: LanPortForwardController::new(net_iface.subscribe()), + net_iface, os_bindings, server_hostnames, }; @@ -169,15 +175,8 @@ impl NetController { #[derive(Default, Debug)] struct HostBinds { - lan: BTreeMap< - u16, - ( - LanInfo, - Option, - BTreeSet, - Vec>, - ), - >, + forwards: BTreeMap)>, + vhosts: BTreeMap<(Option, u16), (TargetInfo, Arc<()>)>, tor: BTreeMap, Vec>)>, } @@ -206,7 +205,7 @@ impl NetService { internal_port: u16, options: BindOptions, ) -> Result<(), Error> { - dbg!("bind", &kind, &id, internal_port, &options); + crate::dbg!("bind", &kind, &id, internal_port, &options); let pkg_id = &self.id; let host = self .net_controller()? @@ -263,134 +262,161 @@ impl NetService { pub async fn update(&mut self, id: HostId, host: Host) -> Result<(), Error> { let ctrl = self.net_controller()?; - let mut hostname_info = BTreeMap::new(); + let mut forwards: BTreeMap = BTreeMap::new(); + let mut vhosts: BTreeMap<(Option, u16), TargetInfo> = BTreeMap::new(); + let mut tor: BTreeMap)> = + BTreeMap::new(); + let mut hostname_info: BTreeMap> = BTreeMap::new(); let binds = self.binds.entry(id.clone()).or_default(); let peek = ctrl.db.peek().await; // LAN let server_info = peek.as_public().as_server_info(); - let ip_info = server_info.as_ip_info().de()?; + let net_ifaces = server_info.as_network_interfaces().de()?; let hostname = server_info.as_hostname().de()?; for (port, bind) in &host.bindings { if !bind.enabled { continue; } - let old_lan_bind = binds.lan.remove(port); - let lan_bind = old_lan_bind - .as_ref() - .filter(|(external, ssl, _, _)| { - ssl == &bind.options.add_ssl && bind.lan == *external - }) - .cloned(); // only keep existing binding if relevant details match - if bind.lan.assigned_port.is_some() || bind.lan.assigned_ssl_port.is_some() { - let new_lan_bind = if let Some(b) = lan_bind { - b - } else { - let mut rcs = Vec::with_capacity(2 + host.addresses.len()); - let mut hostnames = BTreeSet::new(); - if let Some(ssl) = &bind.options.add_ssl { - let external = bind - .lan - .assigned_ssl_port - .or_not_found("assigned ssl port")?; - let target = (self.ip, *port).into(); - let connect_ssl = if let Some(alpn) = ssl.alpn.clone() { - Err(alpn) + if bind.net.assigned_port.is_some() || bind.net.assigned_ssl_port.is_some() { + let mut hostnames = BTreeSet::new(); + if let Some(ssl) = &bind.options.add_ssl { + let external = bind + .net + .assigned_ssl_port + .or_not_found("assigned ssl port")?; + let addr = (self.ip, *port).into(); + let connect_ssl = if let Some(alpn) = ssl.alpn.clone() { + Err(alpn) + } else { + if bind.options.secure.as_ref().map_or(false, |s| s.ssl) { + Ok(()) } else { - if bind.options.secure.as_ref().map_or(false, |s| s.ssl) { - Ok(()) - } else { - Err(AlpnInfo::Reflect) - } - }; - for hostname in ctrl.server_hostnames.iter().cloned() { - rcs.push( - ctrl.vhost - .add(hostname, external, target, connect_ssl.clone()) - .await?, - ); + Err(AlpnInfo::Reflect) } - for address in host.addresses() { - match address { - HostAddress::Onion { address } => { - let hostname = InternedString::from_display(address); - if hostnames.insert(hostname.clone()) { - rcs.push( - ctrl.vhost - .add( - Some(hostname), - external, - target, - connect_ssl.clone(), - ) - .await?, - ); - } + }; + for hostname in ctrl.server_hostnames.iter().cloned() { + vhosts.insert( + (hostname, external), + TargetInfo { + public: bind.net.public, + acme: None, + addr, + connect_ssl: connect_ssl.clone(), + }, + ); + } + for address in host.addresses() { + match address { + HostAddress::Onion { address } => { + let hostname = InternedString::from_display(&address); + if hostnames.insert(hostname.clone()) { + vhosts.insert( + (Some(hostname), external), + TargetInfo { + public: false, + acme: None, + addr, + connect_ssl: connect_ssl.clone(), + }, + ); } - HostAddress::Domain { address } => { - if hostnames.insert(address.clone()) { - let address = Some(address.clone()); - rcs.push( - ctrl.vhost - .add( - address.clone(), - external, - target, - connect_ssl.clone(), - ) - .await?, - ); - if ssl.preferred_external_port == 443 { - rcs.push( - ctrl.vhost - .add( - address.clone(), - 5443, - target, - connect_ssl.clone(), - ) - .await?, + } + HostAddress::Domain { + address, + public, + acme, + } => { + if hostnames.insert(address.clone()) { + let address = Some(address.clone()); + if ssl.preferred_external_port == 443 { + if public && bind.net.public { + vhosts.insert( + (address.clone(), 5443), + TargetInfo { + public: false, + acme: acme.clone(), + addr, + connect_ssl: connect_ssl.clone(), + }, ); } + vhosts.insert( + (address.clone(), 443), + TargetInfo { + public: public && bind.net.public, + acme, + addr, + connect_ssl: connect_ssl.clone(), + }, + ); + } else { + vhosts.insert( + (address.clone(), external), + TargetInfo { + public: public && bind.net.public, + acme, + addr, + connect_ssl: connect_ssl.clone(), + }, + ); } } } } } - if let Some(security) = bind.options.secure { - if bind.options.add_ssl.is_some() && security.ssl { - // doesn't make sense to have 2 listening ports, both with ssl - } else { - let external = - bind.lan.assigned_port.or_not_found("assigned lan port")?; - rcs.push(ctrl.forward.add(external, (self.ip, *port).into()).await?); - } + } + if let Some(security) = bind.options.secure { + if bind.options.add_ssl.is_some() && security.ssl { + // doesn't make sense to have 2 listening ports, both with ssl + } else { + let external = bind.net.assigned_port.or_not_found("assigned lan port")?; + forwards.insert(external, ((self.ip, *port).into(), bind.net.public)); } - (bind.lan, bind.options.add_ssl.clone(), hostnames, rcs) - }; + } let mut bind_hostname_info: Vec = hostname_info.remove(port).unwrap_or_default(); - for (interface, ip_info) in &ip_info { - bind_hostname_info.push(HostnameInfo::Ip { - network_interface_id: interface.clone(), - public: false, - hostname: IpHostname::Local { - value: InternedString::from_display(&{ - let hostname = &hostname; - lazy_format!("{hostname}.local") - }), - port: new_lan_bind.0.assigned_port, - ssl_port: new_lan_bind.0.assigned_ssl_port, - }, - }); + for (interface, public, ip_info) in + net_ifaces.iter().filter_map(|(interface, info)| { + if let Some(ip_info) = &info.ip_info { + Some((interface, info.public(), ip_info)) + } else { + None + } + }) + { + if !public { + bind_hostname_info.push(HostnameInfo::Ip { + network_interface_id: interface.clone(), + public: false, + hostname: IpHostname::Local { + value: InternedString::from_display(&{ + let hostname = &hostname; + lazy_format!("{hostname}.local") + }), + port: bind.net.assigned_port, + ssl_port: bind.net.assigned_ssl_port, + }, + }); + } for address in host.addresses() { - if let HostAddress::Domain { address } = address { - if let Some(ssl) = &new_lan_bind.1 { - if ssl.preferred_external_port == 443 { + if let HostAddress::Domain { + address, + public: domain_public, + .. + } = address + { + if !public || (domain_public && bind.net.public) { + if bind + .options + .add_ssl + .as_ref() + .map_or(false, |ssl| ssl.preferred_external_port == 443) + { bind_hostname_info.push(HostnameInfo::Ip { network_interface_id: interface.clone(), - public: false, + public: public && domain_public && bind.net.public, // TODO: check if port forward is active hostname: IpHostname::Domain { domain: address.clone(), subdomain: None, @@ -398,71 +424,65 @@ impl NetService { ssl_port: Some(443), }, }); + } else { + bind_hostname_info.push(HostnameInfo::Ip { + network_interface_id: interface.clone(), + public, + hostname: IpHostname::Domain { + domain: address.clone(), + subdomain: None, + port: bind.net.assigned_port, + ssl_port: bind.net.assigned_ssl_port, + }, + }); } } } } - if let Some(ipv4) = ip_info.ipv4 { - bind_hostname_info.push(HostnameInfo::Ip { - network_interface_id: interface.clone(), - public: false, - hostname: IpHostname::Ipv4 { - value: ipv4, - port: new_lan_bind.0.assigned_port, - ssl_port: new_lan_bind.0.assigned_ssl_port, - }, - }); - } - if let Some(ipv6) = ip_info.ipv6 { - bind_hostname_info.push(HostnameInfo::Ip { - network_interface_id: interface.clone(), - public: false, - hostname: IpHostname::Ipv6 { - value: ipv6, - port: new_lan_bind.0.assigned_port, - ssl_port: new_lan_bind.0.assigned_ssl_port, - }, - }); + if !public || bind.net.public { + if let Some(wan_ip) = ip_info.wan_ip.filter(|_| public) { + bind_hostname_info.push(HostnameInfo::Ip { + network_interface_id: interface.clone(), + public, + hostname: IpHostname::Ipv4 { + value: wan_ip, + port: bind.net.assigned_port, + ssl_port: bind.net.assigned_ssl_port, + }, + }); + } + for ipnet in &ip_info.subnets { + match ipnet { + IpNet::V4(net) => { + if !public { + bind_hostname_info.push(HostnameInfo::Ip { + network_interface_id: interface.clone(), + public, + hostname: IpHostname::Ipv4 { + value: net.addr(), + port: bind.net.assigned_port, + ssl_port: bind.net.assigned_ssl_port, + }, + }); + } + } + IpNet::V6(net) => { + bind_hostname_info.push(HostnameInfo::Ip { + network_interface_id: interface.clone(), + public: public && !ipv6_is_local(net.addr()), + hostname: IpHostname::Ipv6 { + value: net.addr(), + scope_id: ip_info.scope_id, + port: bind.net.assigned_port, + ssl_port: bind.net.assigned_ssl_port, + }, + }); + } + } + } } } hostname_info.insert(*port, bind_hostname_info); - binds.lan.insert(*port, new_lan_bind); - } - if let Some((lan, _, hostnames, _)) = old_lan_bind { - if let Some(external) = lan.assigned_ssl_port { - for hostname in ctrl.server_hostnames.iter().cloned() { - ctrl.vhost.gc(hostname, external).await?; - } - for hostname in hostnames { - ctrl.vhost.gc(Some(hostname), external).await?; - } - } - if let Some(external) = lan.assigned_port { - ctrl.forward.gc(external).await?; - } - } - } - let mut removed = BTreeSet::new(); - binds.lan.retain(|internal, (external, _, hostnames, _)| { - if host.bindings.get(internal).map_or(false, |b| b.enabled) { - true - } else { - removed.insert((*external, std::mem::take(hostnames))); - - false - } - }); - for (lan, hostnames) in removed { - if let Some(external) = lan.assigned_ssl_port { - for hostname in ctrl.server_hostnames.iter().cloned() { - ctrl.vhost.gc(hostname, external).await?; - } - for hostname in hostnames { - ctrl.vhost.gc(Some(hostname), external).await?; - } - } - if let Some(external) = lan.assigned_port { - ctrl.forward.gc(external).await?; } } @@ -481,7 +501,7 @@ impl NetService { SocketAddr::from((self.ip, *internal)), ); if let (Some(ssl), Some(ssl_internal)) = - (&info.options.add_ssl, info.lan.assigned_ssl_port) + (&info.options.add_ssl, info.net.assigned_ssl_port) { tor_binds.insert( ssl.preferred_external_port, @@ -506,31 +526,13 @@ impl NetService { } } - let mut keep_tor_addrs = BTreeSet::new(); - for tor_addr in host.addresses().filter_map(|a| { - if let HostAddress::Onion { address } = a { - Some(address) - } else { - None - } - }) { - keep_tor_addrs.insert(tor_addr); - let old_tor_bind = binds.tor.remove(tor_addr); - let tor_bind = old_tor_bind.filter(|(ports, _)| ports == &tor_binds); - let new_tor_bind = if let Some(tor_bind) = tor_bind { - tor_bind - } else { - let key = peek - .as_private() - .as_key_store() - .as_onion() - .get_key(tor_addr)?; - let rcs = ctrl - .tor - .add(key, tor_binds.clone().into_iter().collect()) - .await?; - (tor_binds.clone(), rcs) - }; + for tor_addr in host.onions.iter() { + let key = peek + .as_private() + .as_key_store() + .as_onion() + .get_key(tor_addr)?; + tor.insert(key.public().get_onion_address(), (key, tor_binds.clone())); for (internal, ports) in &tor_hostname_ports { let mut bind_hostname_info = hostname_info.remove(internal).unwrap_or_default(); bind_hostname_info.push(HostnameInfo::Onion { @@ -542,16 +544,91 @@ impl NetService { }); hostname_info.insert(*internal, bind_hostname_info); } - binds.tor.insert(tor_addr.clone(), new_tor_bind); } - for addr in binds.tor.keys() { - if !keep_tor_addrs.contains(addr) { - ctrl.tor.gc(Some(addr.clone()), None).await?; + + let all = binds + .forwards + .keys() + .chain(forwards.keys()) + .copied() + .collect::>(); + for external in all { + let mut prev = binds.forwards.remove(&external); + if let Some((internal, public)) = forwards.remove(&external) { + prev = prev.filter(|(i, p, _)| i == &internal && *p == public); + binds.forwards.insert( + external, + if let Some(prev) = prev { + prev + } else { + ( + internal, + public, + ctrl.forward.add(external, public, internal).await?, + ) + }, + ); + } + } + ctrl.forward.gc().await?; + + let all = binds + .vhosts + .keys() + .chain(vhosts.keys()) + .cloned() + .collect::>(); + for key in all { + let mut prev = binds.vhosts.remove(&key); + if let Some(target) = vhosts.remove(&key) { + prev = prev.filter(|(t, _)| t == &target); + binds.vhosts.insert( + key.clone(), + if let Some(prev) = prev { + prev + } else { + (target.clone(), ctrl.vhost.add(key.0, key.1, target)?) + }, + ); + } else { + if let Some((_, rc)) = prev { + drop(rc); + ctrl.vhost.gc(key.0, key.1); + } } } - self.net_controller()? - .db + let all = binds + .tor + .keys() + .chain(tor.keys()) + .cloned() + .collect::>(); + for onion in all { + let mut prev = binds.tor.remove(&onion); + if let Some((key, tor_binds)) = tor.remove(&onion) { + prev = prev.filter(|(b, _)| b == &tor_binds); + binds.tor.insert( + onion, + if let Some(prev) = prev { + prev + } else { + let rcs = ctrl + .tor + .add(key, tor_binds.iter().map(|(k, v)| (*k, *v)).collect()) + .await?; + (tor_binds, rcs) + }, + ); + } else { + if let Some((_, rc)) = prev { + drop(rc); + ctrl.tor.gc(Some(onion), None).await?; + } + } + } + + ctrl.db .mutate(|db| { host_for(db, &self.id, &id, host.kind)? .as_hostname_info_mut() @@ -579,29 +656,6 @@ impl NetService { pub fn get_ip(&self) -> Ipv4Addr { self.ip } - - pub fn get_lan_port(&self, host_id: HostId, internal_port: u16) -> Result { - let host_id_binds = self.binds.get_key_value(&host_id); - match host_id_binds { - Some((_, binds)) => { - if let Some((lan, _, _, _)) = binds.lan.get(&internal_port) { - Ok(*lan) - } else { - Err(Error::new( - eyre!( - "Internal Port {} not found in NetService binds", - internal_port - ), - crate::ErrorKind::NotFound, - )) - } - } - None => Err(Error::new( - eyre!("HostID {} not found in NetService binds", host_id), - crate::ErrorKind::NotFound, - )), - } - } } impl Drop for NetService { diff --git a/core/startos/src/net/network_interface.rs b/core/startos/src/net/network_interface.rs new file mode 100644 index 000000000..991765c86 --- /dev/null +++ b/core/startos/src/net/network_interface.rs @@ -0,0 +1,1116 @@ +use std::collections::{BTreeMap, BTreeSet}; +use std::future::Future; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV6}; +use std::pin::Pin; +use std::sync::{Arc, Weak}; +use std::task::Poll; +use std::time::Duration; + +use clap::Parser; +use futures::{FutureExt, Stream, StreamExt, TryStreamExt}; +use helpers::NonDetachingJoinHandle; +use imbl_value::InternedString; +use ipnet::IpNet; +use itertools::Itertools; +use nix::net::if_::if_nametoindex; +use patch_db::json_ptr::JsonPointer; +use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler}; +use serde::{Deserialize, Serialize}; +use tokio::io::{AsyncBufReadExt, BufReader}; +use tokio::net::{TcpListener, TcpStream}; +use tokio::process::Command; +use tokio::sync::watch; +use ts_rs::TS; +use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream}; +use zbus::zvariant::{ + DeserializeDict, Dict, OwnedObjectPath, OwnedValue, Type as ZType, Value as ZValue, +}; +use zbus::{proxy, Connection}; + +use crate::context::{CliContext, RpcContext}; +use crate::db::model::public::{IpInfo, NetworkInterfaceInfo, NetworkInterfaceType}; +use crate::db::model::Database; +use crate::net::utils::{ipv6_is_link_local, ipv6_is_local}; +use crate::prelude::*; +use crate::util::future::Until; +use crate::util::io::open_file; +use crate::util::serde::{display_serializable, HandlerExtSerde}; +use crate::util::sync::SyncMutex; +use crate::util::Invoke; + +pub fn network_interface_api() -> ParentHandler { + ParentHandler::new() + .subcommand( + "list", + from_fn_async(list_interfaces) + .with_display_serializable() + .with_custom_display_fn(|HandlerArgs { params, .. }, res| { + use prettytable::*; + + if let Some(format) = params.format { + return Ok(display_serializable(format, res)); + } + + let mut table = Table::new(); + table.add_row(row![bc => "INTERFACE", "TYPE", "PUBLIC", "ADDRESSES", "WAN IP"]); + for (iface, info) in res { + table.add_row(row![ + iface, + info.ip_info.as_ref() + .and_then(|ip_info| ip_info.device_type) + .map_or_else(|| "UNKNOWN".to_owned(), |ty| format!("{ty:?}")), + info.public(), + info.ip_info.as_ref().map_or_else( + || "".to_owned(), + |ip_info| ip_info.subnets + .iter() + .map(|ipnet| match ipnet.addr() { + IpAddr::V4(ip) => format!("{ip}/{}", ipnet.prefix_len()), + IpAddr::V6(ip) => format!( + "[{ip}%{}]/{}", + ip_info.scope_id, + ipnet.prefix_len() + ), + }) + .join(", ")), + info.ip_info.as_ref() + .and_then(|ip_info| ip_info.wan_ip) + .map_or_else(|| "N/A".to_owned(), |ip| ip.to_string()) + ]); + } + + table.print_tty(false).unwrap(); + + Ok(()) + }) + .with_about("Show network interfaces StartOS can listen on") + .with_call_remote::(), + ) + .subcommand( + "set-public", + from_fn_async(set_public) + .with_metadata("sync_db", Value::Bool(true)) + .no_display() + .with_about("Indicate whether this interface is publicly addressable") + .with_call_remote::(), + ).subcommand( + "unset-public", + from_fn_async(unset_public) + .with_metadata("sync_db", Value::Bool(true)) + .no_display() + .with_about("Allow this interface to infer whether it is publicly addressable based on its IPv4 address") + .with_call_remote::(), + ).subcommand("forget", + from_fn_async(forget_iface) + .with_metadata("sync_db", Value::Bool(true)) + .no_display() + .with_about("Forget a disconnected interface") + .with_call_remote::() + ) +} + +async fn list_interfaces( + ctx: RpcContext, +) -> Result, Error> { + Ok(ctx.net_controller.net_iface.ip_info.borrow().clone()) +} + +#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] +#[ts(export)] +struct SetPublicParams { + #[ts(type = "string")] + interface: InternedString, + public: Option, +} + +async fn set_public( + ctx: RpcContext, + SetPublicParams { interface, public }: SetPublicParams, +) -> Result<(), Error> { + ctx.net_controller + .net_iface + .set_public(&interface, Some(public.unwrap_or(true))) + .await +} + +#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] +#[ts(export)] +struct UnsetPublicParams { + #[ts(type = "string")] + interface: InternedString, +} + +async fn unset_public( + ctx: RpcContext, + UnsetPublicParams { interface }: UnsetPublicParams, +) -> Result<(), Error> { + ctx.net_controller + .net_iface + .set_public(&interface, None) + .await +} + +#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] +#[ts(export)] +struct ForgetInterfaceParams { + #[ts(type = "string")] + interface: InternedString, +} + +async fn forget_iface( + ctx: RpcContext, + ForgetInterfaceParams { interface }: ForgetInterfaceParams, +) -> Result<(), Error> { + ctx.net_controller.net_iface.forget(&interface).await +} + +#[proxy( + interface = "org.freedesktop.NetworkManager", + default_service = "org.freedesktop.NetworkManager", + default_path = "/org/freedesktop/NetworkManager" +)] +trait NetworkManager { + #[zbus(property)] + fn all_devices(&self) -> Result, Error>; + + #[zbus(signal)] + fn device_added(&self) -> Result<(), Error>; + + #[zbus(signal)] + fn device_removed(&self) -> Result<(), Error>; + + #[zbus(signal)] + fn state_changed(&self) -> Result<(), Error>; +} + +mod active_connection { + use zbus::proxy; + use zbus::zvariant::OwnedObjectPath; + + use crate::prelude::*; + + #[proxy( + interface = "org.freedesktop.NetworkManager.Connection.Active", + default_service = "org.freedesktop.NetworkManager" + )] + pub trait ActiveConnection { + #[zbus(property)] + fn state_flags(&self) -> Result; + + #[zbus(property, name = "Type")] + fn connection_type(&self) -> Result; + + #[zbus(signal)] + fn state_changed(&self) -> Result<(), Error>; + + #[zbus(property)] + fn dhcp4_config(&self) -> Result; + } +} + +#[proxy( + interface = "org.freedesktop.NetworkManager.IP4Config", + default_service = "org.freedesktop.NetworkManager" +)] +trait Ip4Config { + #[zbus(property)] + fn address_data(&self) -> Result, Error>; +} + +#[proxy( + interface = "org.freedesktop.NetworkManager.IP6Config", + default_service = "org.freedesktop.NetworkManager" +)] +trait Ip6Config { + #[zbus(property)] + fn address_data(&self) -> Result, Error>; +} + +#[derive(Clone, Debug, DeserializeDict, ZValue, ZType)] +#[zvariant(signature = "dict")] +struct AddressData { + address: String, + prefix: u32, +} +impl TryFrom for IpNet { + type Error = Error; + fn try_from(value: AddressData) -> Result { + IpNet::new(value.address.parse()?, value.prefix as u8).with_kind(ErrorKind::ParseNetAddress) + } +} + +#[proxy( + interface = "org.freedesktop.NetworkManager.DHCP4Config", + default_service = "org.freedesktop.NetworkManager" +)] +trait Dhcp4Config { + #[zbus(property)] + fn options(&self) -> Result; +} + +#[derive(Clone, Debug, DeserializeDict, ZType)] +#[zvariant(signature = "dict")] +struct Dhcp4Options { + ntp_servers: Option, +} +impl TryFrom for Dhcp4Options { + type Error = zbus::Error; + fn try_from(value: OwnedValue) -> Result { + let dict = value.downcast_ref::()?; + Ok(Self { + ntp_servers: dict.get::<_, String>(&zbus::zvariant::Str::from_static("ntp_servers"))?, + }) + } +} + +mod device { + use zbus::proxy; + use zbus::zvariant::OwnedObjectPath; + + use crate::prelude::*; + + #[proxy( + interface = "org.freedesktop.NetworkManager.Device", + default_service = "org.freedesktop.NetworkManager" + )] + pub trait Device { + #[zbus(property)] + fn ip_interface(&self) -> Result; + + #[zbus(property)] + fn managed(&self) -> Result; + + #[zbus(property)] + fn active_connection(&self) -> Result; + + #[zbus(property)] + fn ip4_config(&self) -> Result; + + #[zbus(property)] + fn ip6_config(&self) -> Result; + + #[zbus(property, name = "State")] + fn _state(&self) -> Result; + + #[zbus(property)] + fn device_type(&self) -> Result; + + #[zbus(signal)] + fn state_changed(&self) -> Result<(), Error>; + } +} + +trait StubStream<'a> { + fn stub(self) -> impl Stream> + 'a; +} +impl<'a, T> StubStream<'a> for PropertyStream<'a, T> +where + T: Unpin + TryFrom + std::fmt::Debug + 'a, + T::Error: Into, +{ + fn stub(self) -> impl Stream> + 'a { + StreamExt::then(self, |d| async move { + PropertyChanged::get(&d).await.map(|_| ()) + }) + .map_err(Error::from) + } +} +impl<'a> StubStream<'a> for SignalStream<'a> { + fn stub(self) -> impl Stream> + 'a { + self.map(|_| Ok(())) + } +} + +#[instrument(skip_all)] +async fn watcher(write_to: watch::Sender>) { + loop { + let res: Result<(), Error> = async { + let connection = Connection::system().await?; + + let netman_proxy = NetworkManagerProxy::new(&connection).await?; + + let mut until = Until::new() + .with_stream(netman_proxy.receive_all_devices_changed().await.stub()) + .with_stream( + netman_proxy + .receive_device_added() + .await? + .into_inner() + .stub(), + ) + .with_stream( + netman_proxy + .receive_device_removed() + .await? + .into_inner() + .stub(), + ) + .with_stream( + netman_proxy + .receive_state_changed() + .await? + .into_inner() + .stub(), + ); + + loop { + until + .run(async { + let devices = netman_proxy.all_devices().await?; + let mut ifaces = BTreeSet::new(); + let mut jobs = Vec::new(); + for device in devices { + let device_proxy = + device::DeviceProxy::new(&connection, device.clone()).await?; + let iface = InternedString::intern(device_proxy.ip_interface().await?); + if iface.is_empty() { + continue; + } + + jobs.push(watch_ip( + &connection, + device_proxy.clone(), + iface.clone(), + &write_to, + )); + ifaces.insert(iface); + } + + write_to.send_if_modified(|m| { + let mut changed = false; + for (iface, info) in m { + if !ifaces.contains(iface) { + info.ip_info = None; + changed = true; + } + } + changed + }); + futures::future::try_join_all(jobs).await?; + + Ok::<_, Error>(()) + }) + .await?; + } + } + .await; + if let Err(e) = res { + tracing::error!("{e}"); + tracing::debug!("{e:?}"); + } + } +} + +async fn get_wan_ipv4(iface: &str) -> Result, Error> { + Ok(reqwest::Client::builder() + .interface(iface) + .build()? + .get("http://ip4only.me/api/") + .timeout(Duration::from_secs(10)) + .send() + .await? + .error_for_status()? + .text() + .await? + .split(",") + .skip(1) + .next() + .filter(|s| !s.is_empty()) + .map(|s| s.parse()) + .transpose()?) +} + +#[instrument(skip(connection, device_proxy, write_to))] +async fn watch_ip( + connection: &Connection, + device_proxy: device::DeviceProxy<'_>, + iface: InternedString, + write_to: &watch::Sender>, +) -> Result<(), Error> { + let mut until = Until::new() + .with_stream( + device_proxy + .receive_active_connection_changed() + .await + .stub(), + ) + .with_stream( + device_proxy + .receive_state_changed() + .await? + .into_inner() + .stub(), + ) + .with_stream(device_proxy.receive_ip4_config_changed().await.stub()) + .with_stream(device_proxy.receive_ip6_config_changed().await.stub()) + .with_async_fn(|| { + async { + tokio::time::sleep(Duration::from_secs(300)).await; + Ok(()) + } + .fuse() + }); + + loop { + until + .run(async { + let ip4_config = device_proxy.ip4_config().await?; + let ip6_config = device_proxy.ip6_config().await?; + + let managed = device_proxy.managed().await?; + if !managed { + return Ok(()); + } + let dac = device_proxy.active_connection().await?; + if &*dac == "/" { + return Ok(()); + } + + let active_connection_proxy = + active_connection::ActiveConnectionProxy::new(&connection, dac).await?; + + let mut until = Until::new() + .with_stream( + active_connection_proxy + .receive_state_changed() + .await? + .into_inner() + .stub(), + ) + .with_stream( + active_connection_proxy + .receive_dhcp4_config_changed() + .await + .stub(), + ); + + loop { + until + .run(async { + let external = active_connection_proxy.state_flags().await? & 0x80 != 0; + if external { + return Ok(()); + } + + let device_type = match device_proxy.device_type().await? { + 1 => Some(NetworkInterfaceType::Ethernet), + 2 => Some(NetworkInterfaceType::Wireless), + 29 => Some(NetworkInterfaceType::Wireguard), + _ => None, + }; + + let dhcp4_config = active_connection_proxy.dhcp4_config().await?; + let ip4_proxy = + Ip4ConfigProxy::new(&connection, ip4_config.clone()).await?; + let ip6_proxy = + Ip6ConfigProxy::new(&connection, ip6_config.clone()).await?; + let mut until = Until::new() + .with_stream(ip4_proxy.receive_address_data_changed().await.stub()) + .with_stream(ip6_proxy.receive_address_data_changed().await.stub()); + + let dhcp4_proxy = if &*dhcp4_config != "/" { + let dhcp4_proxy = + Dhcp4ConfigProxy::new(&connection, dhcp4_config).await?; + until = until.with_stream( + dhcp4_proxy.receive_options_changed().await.stub(), + ); + Some(dhcp4_proxy) + } else { + None + }; + + loop { + until + .run(async { + let addresses = ip4_proxy + .address_data() + .await? + .into_iter() + .chain(ip6_proxy.address_data().await?) + .collect_vec(); + let mut ntp_servers = BTreeSet::new(); + if let Some(dhcp4_proxy) = &dhcp4_proxy { + let dhcp = dhcp4_proxy.options().await?; + if let Some(ntp) = dhcp.ntp_servers { + ntp_servers.extend( + ntp.split_whitespace() + .map(InternedString::intern), + ); + } + } + let scope_id = if_nametoindex(&*iface) + .with_kind(ErrorKind::Network)?; + let subnets: BTreeSet = addresses + .into_iter() + .map(TryInto::try_into) + .try_collect()?; + let ip_info = if !subnets.is_empty() { + let wan_ip = match get_wan_ipv4(&*iface).await { + Ok(a) => a, + Err(e) => { + tracing::error!( + "Failed to determine WAN IP for {iface}: {e}" + ); + tracing::debug!("{e:?}"); + None + } + }; + Some(IpInfo { + scope_id, + device_type, + subnets, + wan_ip, + ntp_servers, + }) + } else { + None + }; + + write_to.send_if_modified(|m| { + let public = m.get(&iface).map_or(None, |i| i.public); + m.insert( + iface.clone(), + NetworkInterfaceInfo { + public, + ip_info: ip_info.clone(), + }, + ) + .filter(|old| &old.ip_info == &ip_info) + .is_none() + }); + + Ok::<_, Error>(()) + }) + .await?; + } + }) + .await?; + } + }) + .await?; + } +} + +pub struct NetworkInterfaceController { + db: TypedPatchDb, + ip_info: watch::Sender>, + _watcher: NonDetachingJoinHandle<()>, + listeners: SyncMutex>>, +} +impl NetworkInterfaceController { + pub fn subscribe(&self) -> watch::Receiver> { + self.ip_info.subscribe() + } + + async fn sync( + db: &TypedPatchDb, + info: &BTreeMap, + ) -> Result<(), Error> { + tracing::debug!("syncronizing {info:?} to db"); + + db.mutate(|db| { + db.as_public_mut() + .as_server_info_mut() + .as_network_interfaces_mut() + .ser(info) + }) + .await?; + + let ntp: BTreeSet<_> = info + .values() + .filter_map(|i| i.ip_info.as_ref()) + .flat_map(|i| &i.ntp_servers) + .cloned() + .collect(); + let prev_ntp = tokio_stream::wrappers::LinesStream::new( + BufReader::new(open_file("/etc/systemd/timesyncd.conf").await?).lines(), + ) + .try_filter_map(|l| async move { + Ok(l.strip_prefix("NTP=").map(|s| { + s.split_whitespace() + .map(InternedString::intern) + .collect::>() + })) + }) + .boxed() + .try_next() + .await? + .unwrap_or_default(); + if ntp != prev_ntp { + // sed -i '/\(^\|#\)NTP=/c\NTP='"${servers}" /etc/systemd/timesyncd.conf + Command::new("sed") + .arg("-i") + .arg( + [r#"/\(^\|#\)NTP=/c\NTP="#] + .into_iter() + .chain(Itertools::intersperse( + { + fn to_str(ntp: &InternedString) -> &str { + &*ntp + } + ntp.iter().map(to_str) + }, + " ", + )) + .join(""), + ) + .arg("/etc/systemd/timesyncd.conf") + .invoke(ErrorKind::Filesystem) + .await?; + Command::new("systemctl") + .arg("restart") + .arg("systemd-timesyncd") + .invoke(ErrorKind::Systemd) + .await?; + } + + Ok(()) + } + pub fn new(db: TypedPatchDb) -> Self { + let (ip_info, mut recv) = watch::channel(BTreeMap::new()); + Self { + db: db.clone(), + ip_info: ip_info.clone(), + _watcher: tokio::spawn(async move { + match db + .peek() + .await + .as_public() + .as_server_info() + .as_network_interfaces() + .de() + { + Ok(mut info) => { + for info in info.values_mut() { + info.ip_info = None; + } + ip_info.send_replace(info); + } + Err(e) => { + tracing::error!("Error loading network interface info: {e}"); + tracing::debug!("{e:?}"); + } + }; + tokio::join!(watcher(ip_info.clone()), async { + let res: Result<(), Error> = async { + loop { + if let Err(e) = async { + let ip_info = { recv.borrow().clone() }; + Self::sync(&db, &ip_info).boxed().await?; + + Ok::<_, Error>(()) + } + .await + { + tracing::error!("Error syncing ip info to db: {e}"); + tracing::debug!("{e:?}"); + } + + let _ = recv.changed().await; + } + } + .await; + if let Err(e) = res { + tracing::error!("Error syncing ip info to db: {e}"); + tracing::debug!("{e:?}"); + } + }); + }) + .into(), + listeners: SyncMutex::new(BTreeMap::new()), + } + } + + pub fn bind(&self, port: u16) -> Result { + let arc = Arc::new(()); + self.listeners.mutate(|l| { + if l.get(&port).filter(|w| w.strong_count() > 0).is_some() { + return Err(Error::new( + std::io::Error::from_raw_os_error(libc::EADDRINUSE), + ErrorKind::Network, + )); + } + l.insert(port, Arc::downgrade(&arc)); + Ok(()) + })?; + let mut ip_info = self.ip_info.subscribe(); + ip_info.mark_changed(); + Ok(NetworkInterfaceListener { + _arc: arc, + ip_info, + changed: None, + listeners: ListenerMap::new(port), + }) + } + + pub fn upgrade_listener( + &self, + listener: impl IntoIterator, + ) -> Result { + let listeners = ListenerMap::from_listener(listener)?; + let port = listeners.port; + let arc = Arc::new(()); + self.listeners.mutate(|l| { + if l.get(&port).filter(|w| w.strong_count() > 0).is_some() { + return Err(Error::new( + std::io::Error::from_raw_os_error(libc::EADDRINUSE), + ErrorKind::Network, + )); + } + l.insert(port, Arc::downgrade(&arc)); + Ok(()) + })?; + let mut ip_info = self.ip_info.subscribe(); + ip_info.mark_changed(); + Ok(NetworkInterfaceListener { + _arc: arc, + ip_info, + changed: None, + listeners, + }) + } + + pub async fn set_public( + &self, + interface: &InternedString, + public: Option, + ) -> Result<(), Error> { + let mut sub = self + .db + .subscribe( + "/public/serverInfo/networkInterfaces" + .parse::>() + .with_kind(ErrorKind::Database)?, + ) + .await; + let mut err = None; + let changed = self.ip_info.send_if_modified(|ip_info| { + let prev = std::mem::replace( + &mut match ip_info.get_mut(interface).or_not_found(interface) { + Ok(a) => a, + Err(e) => { + err = Some(e); + return false; + } + } + .public, + public, + ); + prev != public + }); + if let Some(e) = err { + return Err(e); + } + if changed { + sub.recv().await; + } + Ok(()) + } + + pub async fn forget(&self, interface: &InternedString) -> Result<(), Error> { + let mut sub = self + .db + .subscribe( + "/public/serverInfo/networkInterfaces" + .parse::>() + .with_kind(ErrorKind::Database)?, + ) + .await; + let mut err = None; + let changed = self.ip_info.send_if_modified(|ip_info| { + if ip_info + .get(interface) + .map_or(false, |i| i.ip_info.is_some()) + { + err = Some(Error::new( + eyre!("Cannot forget currently connected interface"), + ErrorKind::InvalidRequest, + )); + return false; + } + ip_info.remove(interface).is_some() + }); + if let Some(e) = err { + return Err(e); + } + if changed { + sub.recv().await; + } + Ok(()) + } +} + +struct ListenerMap { + prev_public: bool, + port: u16, + listeners: BTreeMap)>, +} +impl ListenerMap { + fn from_listener(listener: impl IntoIterator) -> Result { + let mut prev_public = false; + let mut port = 0; + let mut listeners = BTreeMap::)>::new(); + for listener in listener { + let mut local = listener.local_addr().with_kind(ErrorKind::Network)?; + if let SocketAddr::V6(l) = &mut local { + if ipv6_is_link_local(*l.ip()) && l.scope_id() == 0 { + continue; // TODO determine scope id + } + } + if port != 0 && port != local.port() { + return Err(Error::new( + eyre!("Provided listeners are bound to different ports"), + ErrorKind::InvalidRequest, + )); + } + let public = match local.ip() { + IpAddr::V4(ip4) => { + !ip4.is_loopback() + && (!ip4.is_private() || ip4.octets().starts_with(&[10, 59])) // reserving 10.59 for public wireguard configurations + && !ip4.is_link_local() + } + IpAddr::V6(ip6) => !ipv6_is_local(ip6), + }; + prev_public |= public; + port = local.port(); + listeners.insert(local, (listener, public, None)); + } + if port == 0 { + return Err(Error::new( + eyre!("Listener array cannot be empty"), + ErrorKind::InvalidRequest, + )); + } + Ok(Self { + prev_public, + port, + listeners, + }) + } +} +impl ListenerMap { + fn new(port: u16) -> Self { + Self { + prev_public: false, + port, + listeners: BTreeMap::new(), + } + } + + #[instrument(skip(self))] + fn update( + &mut self, + ip_info: &BTreeMap, + public: bool, + ) -> Result<(), Error> { + let mut keep = BTreeSet::::new(); + for info in ip_info.values().chain([&NetworkInterfaceInfo { + public: Some(false), + ip_info: Some(IpInfo { + scope_id: 1, + device_type: None, + subnets: [ + IpNet::new(Ipv4Addr::LOCALHOST.into(), 8).unwrap(), + IpNet::new(Ipv6Addr::LOCALHOST.into(), 128).unwrap(), + ] + .into_iter() + .collect(), + wan_ip: None, + ntp_servers: Default::default(), + }), + }]) { + if public || !info.public() { + if let Some(ip_info) = &info.ip_info { + for ipnet in &ip_info.subnets { + let addr = match ipnet.addr() { + IpAddr::V6(ip6) => SocketAddrV6::new( + ip6, + self.port, + 0, + if ipv6_is_link_local(ip6) { + ip_info.scope_id + } else { + 0 + }, + ) + .into(), + ip => SocketAddr::new(ip, self.port), + }; + keep.insert(addr); + if let Some((_, is_public, wan_ip)) = self.listeners.get_mut(&addr) { + *is_public = info.public(); + *wan_ip = info.ip_info.as_ref().and_then(|i| i.wan_ip); + continue; + } + self.listeners.insert( + addr, + ( + TcpListener::from_std( + mio::net::TcpListener::bind(addr) + .with_ctx(|_| { + ( + ErrorKind::Network, + lazy_format!("binding to {addr:?}"), + ) + })? + .into(), + ) + .with_kind(ErrorKind::Network)?, + info.public(), + info.ip_info.as_ref().and_then(|i| i.wan_ip), + ), + ); + } + } + } + } + self.listeners.retain(|key, _| keep.contains(key)); + self.prev_public = public; + Ok(()) + } + fn poll_accept(&self, cx: &mut std::task::Context<'_>) -> Poll> { + for (bind_addr, listener) in self.listeners.iter() { + if let Poll::Ready((stream, addr)) = listener.0.poll_accept(cx)? { + return Poll::Ready(Ok(Accepted { + stream, + peer: addr, + is_public: listener.1, + wan_ip: listener.2, + bind: *bind_addr, + })); + } + } + Poll::Pending + } +} + +pub struct NetworkInterfaceListener { + ip_info: watch::Receiver>, + listeners: ListenerMap, + changed: Option + Send + Sync + 'static>>>, + _arc: Arc<()>, +} +impl NetworkInterfaceListener { + pub fn port(&self) -> u16 { + self.listeners.port + } + + fn poll_ip_info_changed(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> { + let mut changed = if let Some(changed) = self.changed.take() { + changed + } else { + let mut ip_info = self.ip_info.clone(); + Box::pin(async move { + let _ = ip_info.changed().await; + }) + }; + let res = changed.poll_unpin(cx); + if res.is_pending() { + self.changed = Some(changed); + } + res + } + + pub fn poll_accept( + &mut self, + cx: &mut std::task::Context<'_>, + public: bool, + ) -> Poll> { + if self.poll_ip_info_changed(cx).is_ready() || public != self.listeners.prev_public { + self.listeners.update(&*self.ip_info.borrow(), public)?; + } + self.listeners.poll_accept(cx) + } + + pub async fn accept(&mut self, public: bool) -> Result { + futures::future::poll_fn(|cx| self.poll_accept(cx, public)).await + } +} + +pub struct Accepted { + pub stream: TcpStream, + pub peer: SocketAddr, + pub is_public: bool, + pub wan_ip: Option, + pub bind: SocketAddr, +} + +// async fn _ips() -> Result, Error> { +// Ok(init_ips() +// .await? +// .values() +// .flat_map(|i| { +// std::iter::empty() +// .chain(i.ipv4.map(IpAddr::from)) +// .chain(i.ipv6.map(IpAddr::from)) +// }) +// .collect()) +// } + +// pub async fn ips() -> Result, Error> { +// let ips = CACHED_IPS.read().await.clone(); +// if !ips.is_empty() { +// return Ok(ips); +// } +// let ips = _ips().await?; +// *CACHED_IPS.write().await = ips.clone(); +// Ok(ips) +// } + +// pub async fn init_ips() -> Result, Error> { +// let mut res = BTreeMap::new(); +// let mut ifaces = list_interfaces(); +// while let Some(iface) = ifaces.try_next().await? { +// if iface_is_physical(&iface).await { +// let ip_info = IpInfo::for_interface(&iface).await?; +// res.insert(iface, ip_info); +// } +// } +// Ok(res) +// } + +// // #[command(subcommands(update))] +// pub fn dhcp() -> ParentHandler { +// ParentHandler::new().subcommand( +// "update", +// from_fn_async::<_, _, (), Error, (RpcContext, UpdateParams)>(update) +// .no_display() +// .with_about("Update IP assigned by dhcp") +// .with_call_remote::(), +// ) +// } +// #[derive(Deserialize, Serialize, Parser, TS)] +// #[serde(rename_all = "camelCase")] +// #[command(rename_all = "kebab-case")] +// pub struct UpdateParams { +// interface: String, +// } + +// pub async fn update( +// ctx: RpcContext, +// UpdateParams { interface }: UpdateParams, +// ) -> Result<(), Error> { +// if iface_is_physical(&interface).await { +// let ip_info = IpInfo::for_interface(&interface).await?; +// ctx.db +// .mutate(|db| { +// db.as_public_mut() +// .as_server_info_mut() +// .as_ip_info_mut() +// .insert(&interface, &ip_info) +// }) +// .await?; + +// let mut cached = CACHED_IPS.write().await; +// if cached.is_empty() { +// *cached = _ips().await?; +// } else { +// cached.extend( +// std::iter::empty() +// .chain(ip_info.ipv4.map(IpAddr::from)) +// .chain(ip_info.ipv6.map(IpAddr::from)), +// ); +// } +// } +// Ok(()) +// } diff --git a/core/startos/src/net/service_interface.rs b/core/startos/src/net/service_interface.rs index ade10d959..ad2900da7 100644 --- a/core/startos/src/net/service_interface.rs +++ b/core/startos/src/net/service_interface.rs @@ -12,7 +12,8 @@ use ts_rs::TS; #[serde(tag = "kind")] pub enum HostnameInfo { Ip { - network_interface_id: String, + #[ts(type = "string")] + network_interface_id: InternedString, public: bool, hostname: IpHostname, }, @@ -43,6 +44,8 @@ pub enum IpHostname { }, Ipv6 { value: Ipv6Addr, + #[serde(default)] + scope_id: u32, port: Option, ssl_port: Option, }, @@ -69,7 +72,6 @@ pub struct ServiceInterface { pub id: ServiceInterfaceId, pub name: String, pub description: String, - pub has_primary: bool, pub masked: bool, pub address_info: AddressInfo, #[serde(rename = "type")] diff --git a/core/startos/src/net/ssl.rs b/core/startos/src/net/ssl.rs index 29bcd9652..a89853591 100644 --- a/core/startos/src/net/ssl.rs +++ b/core/startos/src/net/ssl.rs @@ -17,7 +17,6 @@ use openssl::x509::{X509Builder, X509Extension, X509NameBuilder, X509}; use openssl::*; use patch_db::HasModel; use serde::{Deserialize, Serialize}; -use tokio::time::Instant; use tracing::instrument; use crate::account::AccountInfo; diff --git a/core/startos/src/net/static_server.rs b/core/startos/src/net/static_server.rs index c070d7920..d1070f9e1 100644 --- a/core/startos/src/net/static_server.rs +++ b/core/startos/src/net/static_server.rs @@ -8,15 +8,15 @@ use std::time::UNIX_EPOCH; use async_compression::tokio::bufread::GzipEncoder; use axum::body::Body; use axum::extract::{self as x, Request}; -use axum::response::Response; -use axum::routing::{any, get, post}; +use axum::response::{Redirect, Response}; +use axum::routing::{any, get}; use axum::Router; use base64::display::Base64Display; use digest::Digest; use futures::future::ready; use http::header::{ ACCEPT_ENCODING, ACCEPT_RANGES, CACHE_CONTROL, CONNECTION, CONTENT_ENCODING, CONTENT_LENGTH, - CONTENT_RANGE, CONTENT_TYPE, ETAG, RANGE, + CONTENT_RANGE, CONTENT_TYPE, ETAG, HOST, RANGE, }; use http::request::Parts as RequestParts; use http::{HeaderValue, Method, StatusCode}; @@ -26,7 +26,6 @@ use new_mime_guess::MimeGuess; use openssl::hash::MessageDigest; use openssl::x509::X509; use rpc_toolkit::{Context, HttpServer, Server}; -use sqlx::query; use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeekExt, BufReader}; use tokio_util::io::ReaderStream; use url::Url; @@ -47,7 +46,7 @@ use crate::s9pk::S9pk; use crate::util::io::open_file; use crate::util::net::SyncBody; use crate::util::serde::BASE64; -use crate::{diagnostic_api, init_api, install_api, main_api, setup_api}; +use crate::{diagnostic_api, init_api, install_api, main_api, setup_api, DATA_DIR}; const NOT_FOUND: &[u8] = b"Not Found"; const METHOD_NOT_ALLOWED: &[u8] = b"Method Not Allowed"; @@ -230,6 +229,20 @@ pub fn refresher() -> Router { })) } +pub fn redirecter() -> Router { + Router::new().fallback(get(|request: Request| async move { + Redirect::temporary(&format!( + "https://{}{}", + request + .headers() + .get(HOST) + .and_then(|s| s.to_str().ok()) + .unwrap_or("localhost"), + request.uri() + )) + })) +} + async fn proxy_request(ctx: RpcContext, request: Request, url: String) -> Result { if_authorized(&ctx, request, |mut request| async { for header in PROXY_STRIP_HEADERS { @@ -253,7 +266,7 @@ fn s9pk_router(ctx: RpcContext) -> Router { let (parts, _) = request.into_parts(); match FileData::from_path( &parts, - &ctx.datadir + &Path::new(DATA_DIR) .join(PKG_ARCHIVE_DIR) .join("installed") .join(s9pk), @@ -279,7 +292,7 @@ fn s9pk_router(ctx: RpcContext) -> Router { let s9pk = S9pk::deserialize( &MultiCursorFile::from( open_file( - ctx.datadir + Path::new(DATA_DIR) .join(PKG_ARCHIVE_DIR) .join("installed") .join(s9pk), diff --git a/core/startos/src/net/utils.rs b/core/startos/src/net/utils.rs index 9cba8a0cd..d6dcdde15 100644 --- a/core/startos/src/net/utils.rs +++ b/core/startos/src/net/utils.rs @@ -1,16 +1,25 @@ -use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV6}; use std::path::Path; use async_stream::try_stream; use color_eyre::eyre::eyre; use futures::stream::BoxStream; use futures::{StreamExt, TryStreamExt}; -use ipnet::{Ipv4Net, Ipv6Net}; +use ipnet::{IpNet, Ipv4Net, Ipv6Net}; +use nix::net::if_::if_nametoindex; use tokio::net::{TcpListener, TcpStream}; use tokio::process::Command; +use crate::prelude::*; use crate::util::Invoke; -use crate::Error; + +pub fn ipv6_is_link_local(addr: Ipv6Addr) -> bool { + (addr.segments()[0] & 0xffc0) == 0xfe80 +} + +pub fn ipv6_is_local(addr: Ipv6Addr) -> bool { + addr.is_loopback() || (addr.segments()[0] & 0xfe00) == 0xfc00 || ipv6_is_link_local(addr) +} fn parse_iface_ip(output: &str) -> Result, Error> { let output = output.trim(); @@ -112,6 +121,52 @@ pub async fn find_eth_iface() -> Result { )) } +pub async fn all_socket_addrs_for(port: u16) -> Result, Error> { + let mut res = Vec::new(); + + let raw = String::from_utf8( + Command::new("ip") + .arg("-o") + .arg("addr") + .arg("show") + .invoke(ErrorKind::ParseSysInfo) + .await?, + )?; + let err = |item: &str, lineno: usize, line: &str| { + Error::new( + eyre!("failed to parse ip info ({item}[line:{lineno}]) from {line:?}"), + ErrorKind::ParseSysInfo, + ) + }; + for (idx, line) in raw + .lines() + .map(|l| l.trim()) + .enumerate() + .filter(|(_, l)| !l.is_empty()) + { + let mut split = line.split_whitespace(); + let _num = split.next(); + let ifname = split.next().ok_or_else(|| err("ifname", idx, line))?; + let _kind = split.next(); + let ipnet_str = split.next().ok_or_else(|| err("ipnet", idx, line))?; + let ipnet = ipnet_str + .parse::() + .with_ctx(|_| (ErrorKind::ParseSysInfo, err("ipnet", idx, ipnet_str)))?; + match ipnet.addr() { + IpAddr::V4(ip4) => res.push(SocketAddr::new(ip4.into(), port)), + IpAddr::V6(ip6) => res.push(SocketAddr::V6(SocketAddrV6::new( + ip6, + port, + 0, + if_nametoindex(ifname) + .with_ctx(|_| (ErrorKind::ParseSysInfo, "reading scope_id"))?, + ))), + } + } + + Ok(res) +} + pub struct TcpListeners { listeners: Vec, } diff --git a/core/startos/src/net/vhost.rs b/core/startos/src/net/vhost.rs index fb7c6f957..dc6f422bf 100644 --- a/core/startos/src/net/vhost.rs +++ b/core/startos/src/net/vhost.rs @@ -1,22 +1,24 @@ -use std::collections::BTreeMap; -use std::net::{IpAddr, Ipv6Addr, SocketAddr}; +use std::collections::{BTreeMap, BTreeSet}; +use std::net::{IpAddr, SocketAddr}; use std::str::FromStr; use std::sync::{Arc, Weak}; use std::time::Duration; -use async_acme::acme::ACME_TLS_ALPN_NAME; +use async_acme::acme::{Identifier, ACME_TLS_ALPN_NAME}; use axum::body::Body; use axum::extract::Request; use axum::response::Response; use color_eyre::eyre::eyre; +use futures::FutureExt; use helpers::NonDetachingJoinHandle; use http::Uri; use imbl_value::InternedString; use models::ResultExt; +use rpc_toolkit::{from_fn, Context, HandlerArgs, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; use tokio::io::AsyncWriteExt; -use tokio::net::{TcpListener, TcpStream}; -use tokio::sync::{watch, Mutex, RwLock}; +use tokio::net::TcpStream; +use tokio::sync::watch; use tokio_rustls::rustls::crypto::CryptoProvider; use tokio_rustls::rustls::pki_types::{ CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer, ServerName, @@ -30,14 +32,61 @@ use tokio_stream::StreamExt; use tracing::instrument; use ts_rs::TS; +use crate::context::{CliContext, RpcContext}; use crate::db::model::Database; -use crate::net::acme::AcmeCertCache; +use crate::net::acme::{AcmeCertCache, AcmeProvider}; +use crate::net::network_interface::{ + Accepted, NetworkInterfaceController, NetworkInterfaceListener, +}; use crate::net::static_server::server_error; use crate::prelude::*; use crate::util::io::BackTrackingIO; -use crate::util::serde::MaybeUtf8String; +use crate::util::serde::{display_serializable, HandlerExtSerde, MaybeUtf8String}; use crate::util::sync::SyncMutex; +pub fn vhost_api() -> ParentHandler { + ParentHandler::new().subcommand( + "dump-table", + from_fn(|ctx: RpcContext| Ok(ctx.net_controller.vhost.dump_table())) + .with_display_serializable() + .with_custom_display_fn(|HandlerArgs { params, .. }, res| { + use prettytable::*; + + if let Some(format) = params.format { + display_serializable(format, res); + return Ok::<_, Error>(()); + } + + let mut table = Table::new(); + table.add_row(row![bc => "FROM", "TO", "PUBLIC", "ACME", "CONNECT SSL", "ACTIVE"]); + + for (external, targets) in res { + for (host, targets) in targets { + for (idx, target) in targets.into_iter().enumerate() { + table.add_row(row![ + format!( + "{}:{}", + host.as_ref().map(|s| &**s).unwrap_or("*"), + external.0 + ), + target.addr, + target.public, + target.acme.as_ref().map(|a| a.0.as_str()).unwrap_or("NONE"), + target.connect_ssl.is_ok(), + idx == 0 + ]); + } + } + } + + table.print_tty(false)?; + + Ok(()) + }) + .with_call_remote::(), + ) +} + #[derive(Debug)] struct SingleCertResolver(Arc); impl ResolvesServerCert for SingleCertResolver { @@ -49,62 +98,108 @@ impl ResolvesServerCert for SingleCertResolver { // not allowed: <=1024, >=32768, 5355, 5432, 9050, 6010, 9051, 5353 pub struct VHostController { - crypto_provider: Arc, db: TypedPatchDb, - servers: Mutex>, + interfaces: Arc, + crypto_provider: Arc, + acme_tls_alpn_cache: AcmeTlsAlpnCache, + servers: SyncMutex>, } impl VHostController { - pub fn new(db: TypedPatchDb) -> Self { + pub fn new(db: TypedPatchDb, interfaces: Arc) -> Self { Self { - crypto_provider: Arc::new(tokio_rustls::rustls::crypto::ring::default_provider()), db, - servers: Mutex::new(BTreeMap::new()), + interfaces, + crypto_provider: Arc::new(tokio_rustls::rustls::crypto::ring::default_provider()), + acme_tls_alpn_cache: Arc::new(SyncMutex::new(BTreeMap::new())), + servers: SyncMutex::new(BTreeMap::new()), } } #[instrument(skip_all)] - pub async fn add( + pub fn add( &self, hostname: Option, external: u16, - target: SocketAddr, - connect_ssl: Result<(), AlpnInfo>, // Ok: yes, connect using ssl, pass through alpn; Err: connect tcp, use provided strategy for alpn + TargetInfo { + public, + acme, + addr, + connect_ssl, + }: TargetInfo, ) -> Result, Error> { - let mut writable = self.servers.lock().await; - let server = if let Some(server) = writable.remove(&external) { - server - } else { - tracing::info!("Listening on {external}"); - VHostServer::new(external, self.db.clone(), self.crypto_provider.clone()).await? - }; - let rc = server - .add( + self.servers.mutate(|writable| { + let server = if let Some(server) = writable.remove(&external) { + server + } else { + VHostServer::new( + external, + self.db.clone(), + self.interfaces.clone(), + self.crypto_provider.clone(), + self.acme_tls_alpn_cache.clone(), + )? + }; + let rc = server.add( hostname, TargetInfo { - addr: target, + public, + acme, + addr, connect_ssl, }, - ) - .await; - writable.insert(external, server); - Ok(rc?) + ); + writable.insert(external, server); + Ok(rc?) + }) } + + pub fn dump_table( + &self, + ) -> BTreeMap, BTreeMap>, BTreeSet>> + { + self.servers.peek(|s| { + s.iter() + .map(|(k, v)| { + ( + JsonKey::new(*k), + v.mapping + .borrow() + .iter() + .map(|(k, v)| { + ( + JsonKey::new(k.clone()), + v.iter() + .filter(|(_, v)| v.strong_count() > 0) + .map(|(k, _)| k) + .cloned() + .collect(), + ) + }) + .collect(), + ) + }) + .collect() + }) + } + #[instrument(skip_all)] - pub async fn gc(&self, hostname: Option, external: u16) -> Result<(), Error> { - let mut writable = self.servers.lock().await; - if let Some(server) = writable.remove(&external) { - server.gc(hostname).await?; - if !server.is_empty().await? { - writable.insert(external, server); + pub fn gc(&self, hostname: Option, external: u16) { + self.servers.mutate(|writable| { + if let Some(server) = writable.remove(&external) { + server.gc(hostname); + if !server.is_empty() { + writable.insert(external, server); + } } - } - Ok(()) + }) } } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] -struct TargetInfo { - addr: SocketAddr, - connect_ssl: Result<(), AlpnInfo>, +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] +pub struct TargetInfo { + pub public: bool, + pub acme: Option, + pub addr: SocketAddr, + pub connect_ssl: Result<(), AlpnInfo>, // Ok: yes, connect using ssl, pass through alpn; Err: connect tcp, use provided strategy for alpn } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] @@ -120,425 +215,498 @@ impl Default for AlpnInfo { } } +type AcmeTlsAlpnCache = + Arc>>>>>; +type Mapping = BTreeMap, BTreeMap>>; + struct VHostServer { - mapping: Weak, BTreeMap>>>>, + mapping: watch::Sender, _thread: NonDetachingJoinHandle<()>, } + impl VHostServer { - #[instrument(skip_all)] - async fn new( - port: u16, + async fn accept( + listener: &mut NetworkInterfaceListener, + mut mapping: watch::Receiver, db: TypedPatchDb, + acme_tls_alpn_cache: AcmeTlsAlpnCache, crypto_provider: Arc, - ) -> Result { - let acme_tls_alpn_cache = Arc::new(SyncMutex::new(BTreeMap::< - InternedString, - watch::Receiver>>, - >::new())); - // check if port allowed - let listener = TcpListener::bind(SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), port)) - .await - .with_kind(crate::ErrorKind::Network)?; - let mapping = Arc::new(RwLock::new(BTreeMap::new())); - Ok(Self { - mapping: Arc::downgrade(&mapping), - _thread: tokio::spawn(async move { - loop { - match listener.accept().await { - Ok((stream, _)) => { - if let Err(e) = socket2::SockRef::from(&stream).set_tcp_keepalive( - &socket2::TcpKeepalive::new() - .with_time(Duration::from_secs(900)) - .with_interval(Duration::from_secs(60)) - .with_retries(5), - ) { - tracing::error!("Failed to set tcp keepalive: {e}"); - tracing::debug!("{e:?}"); - } + ) -> Result<(), Error> { + let accepted; - let mut stream = BackTrackingIO::new(stream); - let mapping = mapping.clone(); - let db = db.clone(); - let acme_tls_alpn_cache = acme_tls_alpn_cache.clone(); - let crypto_provider = crypto_provider.clone(); - tokio::spawn(async move { - if let Err(e) = async { - let mid: tokio_rustls::StartHandshake<&mut BackTrackingIO> = match LazyConfigAcceptor::new( - Acceptor::default(), - &mut stream, - ) - .await - { - Ok(a) => a, - Err(_) => { - stream.rewind(); - return hyper_util::server::conn::auto::Builder::new(hyper_util::rt::TokioExecutor::new()) - .serve_connection( - hyper_util::rt::TokioIo::new(stream), - hyper_util::service::TowerToHyperService::new(axum::Router::new().fallback( - axum::routing::method_routing::any(move |req: Request| async move { - match async move { - let host = req - .headers() - .get(http::header::HOST) - .and_then(|host| host.to_str().ok()); - let uri = Uri::from_parts({ - let mut parts = req.uri().to_owned().into_parts(); - parts.scheme = Some("https".parse()?); - parts.authority = host.map(FromStr::from_str).transpose()?; - parts - })?; - Response::builder() - .status(http::StatusCode::TEMPORARY_REDIRECT) - .header(http::header::LOCATION, uri.to_string()) - .body(Body::default()) - }.await { - Ok(a) => a, - Err(e) => { - tracing::warn!("Error redirecting http request on ssl port: {e}"); - tracing::error!("{e:?}"); - server_error(Error::new(e, ErrorKind::Network)) - } - } - }), - )), - ) - .await - .map_err(|e| Error::new(color_eyre::eyre::Report::msg(e), ErrorKind::Network)); + loop { + let any_public = mapping + .borrow() + .iter() + .any(|(_, targets)| targets.iter().any(|(target, _)| target.public)); + + let changed_public = mapping + .wait_for(|m| { + m.iter() + .any(|(_, targets)| targets.iter().any(|(target, _)| target.public)) + != any_public + }) + .boxed(); + + tokio::select! { + a = listener.accept(any_public) => { + accepted = a?; + break; + } + _ = changed_public => { + tracing::debug!("port {} {} public bindings", listener.port(), if any_public { "no longer has" } else { "now has" }); + } + } + } + + if let Err(e) = socket2::SockRef::from(&accepted.stream).set_tcp_keepalive( + &socket2::TcpKeepalive::new() + .with_time(Duration::from_secs(900)) + .with_interval(Duration::from_secs(60)) + .with_retries(5), + ) { + tracing::error!("Failed to set tcp keepalive: {e}"); + tracing::debug!("{e:?}"); + } + + tokio::spawn(async move { + let bind = accepted.bind; + if let Err(e) = + Self::handle_stream(accepted, mapping, db, acme_tls_alpn_cache, crypto_provider) + .await + { + tracing::error!("Error in VHostController on {bind}: {e}"); + tracing::debug!("{e:?}") + } + }); + Ok(()) + } + + async fn handle_stream( + Accepted { + stream, + is_public, + wan_ip, + bind, + .. + }: Accepted, + mapping: watch::Receiver, + db: TypedPatchDb, + acme_tls_alpn_cache: AcmeTlsAlpnCache, + crypto_provider: Arc, + ) -> Result<(), Error> { + let mut stream = BackTrackingIO::new(stream); + let mid: tokio_rustls::StartHandshake<&mut BackTrackingIO> = + match LazyConfigAcceptor::new(Acceptor::default(), &mut stream).await { + Ok(a) => a, + Err(e) => { + let (_, buf) = stream.rewind(); + if std::str::from_utf8(buf) + .ok() + .and_then(|buf| { + buf.lines() + .map(|l| l.trim()) + .filter(|l| !l.is_empty()) + .next() + }) + .map_or(false, |buf| { + regex::Regex::new("[A-Z]+ (.+) HTTP/1") + .unwrap() + .is_match(buf) + }) + { + return hyper_util::server::conn::auto::Builder::new( + hyper_util::rt::TokioExecutor::new(), + ) + .serve_connection( + hyper_util::rt::TokioIo::new(stream), + hyper_util::service::TowerToHyperService::new( + axum::Router::new().fallback(axum::routing::method_routing::any( + move |req: Request| async move { + match async move { + let host = req + .headers() + .get(http::header::HOST) + .and_then(|host| host.to_str().ok()); + let uri = Uri::from_parts({ + let mut parts = req.uri().to_owned().into_parts(); + parts.scheme = Some("https".parse()?); + parts.authority = + host.map(FromStr::from_str).transpose()?; + parts + })?; + Response::builder() + .status(http::StatusCode::TEMPORARY_REDIRECT) + .header(http::header::LOCATION, uri.to_string()) + .body(Body::default()) } - }; - let target_name = - mid.client_hello().server_name().map(|s| s.into()); - let target = { - let mapping = mapping.read().await; - mapping - .get(&target_name) - .into_iter() - .flatten() - .find(|(_, rc)| rc.strong_count() > 0) - .or_else(|| { - if target_name - .as_ref() - .map(|s| s.parse::().is_ok()) - .unwrap_or(true) - { - mapping - .get(&None) - .into_iter() - .flatten() - .find(|(_, rc)| rc.strong_count() > 0) - } else { - None - } - }) - .map(|(target, _)| target.clone()) - }; - if let Some(target) = target { - let peek = db.peek().await; - let root = peek.as_private().as_key_store().as_local_certs().as_root_cert().de()?; - let mut cfg = match async { - if let Some(acme_settings) = peek.as_public().as_server_info().as_acme().de()? { - if let Some(domain) = target_name.as_ref().filter(|target_name| acme_settings.domains.contains(*target_name)) { - if mid - .client_hello() - .alpn() - .into_iter() - .flatten() - .any(|alpn| alpn == ACME_TLS_ALPN_NAME) - { - let cert = WatchStream::new( - acme_tls_alpn_cache.peek(|c| c.get(&**domain).cloned()) - .ok_or_else(|| { - Error::new( - eyre!("No challenge recv available for {domain}"), - ErrorKind::OpenSsl - ) - })?, - ); - tracing::info!("Waiting for verification cert for {domain}"); - let cert = cert - .filter(|c| c.is_some()) - .next() - .await - .flatten() - .ok_or_else(|| { - Error::new(eyre!("No challenge available for {domain}"), ErrorKind::OpenSsl) - })?; - tracing::info!("Verification cert received for {domain}"); - let mut cfg = ServerConfig::builder_with_provider(crypto_provider.clone()) - .with_safe_default_protocol_versions() - .with_kind(crate::ErrorKind::OpenSsl)? - .with_no_client_auth() - .with_cert_resolver(Arc::new(SingleCertResolver(cert))); - - cfg.alpn_protocols = vec![ACME_TLS_ALPN_NAME.to_vec()]; - return Ok(Err(cfg)); - } else { - let domains = [domain.to_string()]; - let (send, recv) = watch::channel(None); - acme_tls_alpn_cache.mutate(|c| c.insert(domain.clone(), recv)); - let cert = - async_acme::rustls_helper::order( - |_, cert| { - send.send_replace(Some(Arc::new(cert))); - Ok(()) - }, - acme_settings.provider.as_str(), - &domains, - Some(&AcmeCertCache(&db)), - &acme_settings.contact, - ) - .await - .with_kind(ErrorKind::OpenSsl)?; - return Ok(Ok( - ServerConfig::builder_with_provider(crypto_provider.clone()) - .with_safe_default_protocol_versions() - .with_kind(crate::ErrorKind::OpenSsl)? - .with_no_client_auth() - .with_cert_resolver(Arc::new(SingleCertResolver(Arc::new(cert)))) - )); - } - } - } - let hostnames = target_name - .into_iter() - .chain( - peek - .as_public() - .as_server_info() - .as_ip_info() - .as_entries()? - .into_iter() - .flat_map(|(_, ips)| [ - ips.as_ipv4().de().map(|ip| ip.map(IpAddr::V4)), - ips.as_ipv6().de().map(|ip| ip.map(IpAddr::V6)) - ]) - .filter_map(|a| a.transpose()) - .map(|a| a.map(|ip| InternedString::from_display(&ip))) - .collect::, _>>()?, - ) - .collect(); - let key = db - .mutate(|v| { - v.as_private_mut() - .as_key_store_mut() - .as_local_certs_mut() - .cert_for(&hostnames) - }) - .await?; - let cfg = ServerConfig::builder_with_provider(crypto_provider.clone()) - .with_safe_default_protocol_versions() - .with_kind(crate::ErrorKind::OpenSsl)? - .with_no_client_auth(); - if mid.client_hello().signature_schemes().contains( - &tokio_rustls::rustls::SignatureScheme::ED25519, - ) { - cfg.with_single_cert( - key.fullchain_ed25519() - .into_iter() - .map(|c| { - Ok(tokio_rustls::rustls::pki_types::CertificateDer::from( - c.to_der()?, - )) - }) - .collect::>()?, - PrivateKeyDer::from(PrivatePkcs8KeyDer::from( - key.leaf - .keys - .ed25519 - .private_key_to_pkcs8()?, - )), - ) - } else { - cfg.with_single_cert( - key.fullchain_nistp256() - .into_iter() - .map(|c| { - Ok(tokio_rustls::rustls::pki_types::CertificateDer::from( - c.to_der()?, - )) - }) - .collect::>()?, - PrivateKeyDer::from(PrivatePkcs8KeyDer::from( - key.leaf - .keys - .nistp256 - .private_key_to_pkcs8()?, - )), - ) - } - .with_kind(crate::ErrorKind::OpenSsl) - .map(Ok) - }.await? { + .await + { Ok(a) => a, - Err(cfg) => { - tracing::info!("performing ACME auth challenge"); - let mut accept = mid.into_stream(Arc::new(cfg)); - let io = accept.get_mut().unwrap(); - let buffered = io.stop_buffering(); - io.write_all(&buffered).await?; - accept.await?; - tracing::info!("ACME auth challenge completed"); - return Ok(()); - } - }; - let mut tcp_stream = - TcpStream::connect(target.addr).await?; - match target.connect_ssl { - Ok(()) => { - let mut client_cfg = - tokio_rustls::rustls::ClientConfig::builder_with_provider(crypto_provider) - .with_safe_default_protocol_versions() - .with_kind(crate::ErrorKind::OpenSsl)? - .with_root_certificates({ - let mut store = RootCertStore::empty(); - store.add( - CertificateDer::from( - root.to_der()?, - ), - ).with_kind(crate::ErrorKind::OpenSsl)?; - store - }) - .with_no_client_auth(); - client_cfg.alpn_protocols = mid - .client_hello() - .alpn() - .into_iter() - .flatten() - .map(|x| x.to_vec()) - .collect(); - let mut target_stream = - TlsConnector::from(Arc::new(client_cfg)) - .connect_with( - ServerName::IpAddress( - target.addr.ip().into(), - ), - tcp_stream, - |conn| { - cfg.alpn_protocols.extend( - conn.alpn_protocol() - .into_iter() - .map(|p| p.to_vec()), - ) - }, - ) - .await - .with_kind(crate::ErrorKind::OpenSsl)?; - let mut accept = mid.into_stream(Arc::new(cfg)); - let io = accept.get_mut().unwrap(); - let buffered = io.stop_buffering(); - io.write_all(&buffered).await?; - let mut tls_stream = - match accept.await { - Ok(a) => a, - Err(e) => { - tracing::trace!( "VHostController: failed to accept TLS connection on port {port}: {e}"); - tracing::trace!("{e:?}"); - return Ok(()) - } - }; - tokio::io::copy_bidirectional( - &mut tls_stream, - &mut target_stream, - ) - .await - } - Err(AlpnInfo::Reflect) => { - for proto in - mid.client_hello().alpn().into_iter().flatten() - { - cfg.alpn_protocols.push(proto.into()); - } - let mut accept = mid.into_stream(Arc::new(cfg)); - let io = accept.get_mut().unwrap(); - let buffered = io.stop_buffering(); - io.write_all(&buffered).await?; - let mut tls_stream = - match accept.await { - Ok(a) => a, - Err(e) => { - tracing::trace!( "VHostController: failed to accept TLS connection on port {port}: {e}"); - tracing::trace!("{e:?}"); - return Ok(()) - } - }; - tokio::io::copy_bidirectional( - &mut tls_stream, - &mut tcp_stream, - ) - .await - } - Err(AlpnInfo::Specified(alpn)) => { - cfg.alpn_protocols = alpn.into_iter().map(|a| a.0).collect(); - let mut accept = mid.into_stream(Arc::new(cfg)); - let io = accept.get_mut().unwrap(); - let buffered = io.stop_buffering(); - io.write_all(&buffered).await?; - let mut tls_stream = - match accept.await { - Ok(a) => a, - Err(e) => { - tracing::trace!( "VHostController: failed to accept TLS connection on port {port}: {e}"); - tracing::trace!("{e:?}"); - return Ok(()) - } - }; - tokio::io::copy_bidirectional( - &mut tls_stream, - &mut tcp_stream, - ) - .await + Err(e) => { + tracing::warn!( + "Error redirecting http request on ssl port: {e}" + ); + tracing::error!("{e:?}"); + server_error(Error::new(e, ErrorKind::Network)) } } - .map_or_else( - |e| { - use std::io::ErrorKind as E; - match e.kind() { - E::UnexpectedEof | E::BrokenPipe | E::ConnectionAborted | E::ConnectionReset | E::ConnectionRefused | E::TimedOut | E::Interrupted | E::NotConnected => Ok(()), - _ => Err(e), - }}, - |_| Ok(()), - )?; - } else { - // 503 - } - Ok::<_, Error>(()) - } - .await - { - tracing::error!("Error in VHostController on port {port}: {e}"); - tracing::debug!("{e:?}") - } - }); + }, + )), + ), + ) + .await + .map_err(|e| { + Error::new(color_eyre::eyre::Report::msg(e), ErrorKind::Network) + }); + } else { + return Err(e).with_kind(ErrorKind::Network); + } + } + }; + let target_name: Option = + mid.client_hello().server_name().map(|s| s.into()); + if let Some(domain) = target_name.as_ref() { + if mid + .client_hello() + .alpn() + .into_iter() + .flatten() + .any(|alpn| alpn == ACME_TLS_ALPN_NAME) + { + let cert = WatchStream::new( + acme_tls_alpn_cache + .peek(|c| c.get(&**domain).cloned()) + .ok_or_else(|| { + Error::new( + eyre!("No challenge recv available for {domain}"), + ErrorKind::OpenSsl, + ) + })?, + ); + tracing::info!("Waiting for verification cert for {domain}"); + let cert = cert + .filter(|c| c.is_some()) + .next() + .await + .flatten() + .ok_or_else(|| { + Error::new( + eyre!("No challenge available for {domain}"), + ErrorKind::OpenSsl, + ) + })?; + tracing::info!("Verification cert received for {domain}"); + let mut cfg = ServerConfig::builder_with_provider(crypto_provider.clone()) + .with_safe_default_protocol_versions() + .with_kind(crate::ErrorKind::OpenSsl)? + .with_no_client_auth() + .with_cert_resolver(Arc::new(SingleCertResolver(cert))); + + cfg.alpn_protocols = vec![ACME_TLS_ALPN_NAME.to_vec()]; + tracing::info!("performing ACME auth challenge"); + let mut accept = mid.into_stream(Arc::new(cfg)); + let io = accept.get_mut().unwrap(); + let buffered = io.stop_buffering(); + io.write_all(&buffered).await?; + accept.await?; + tracing::info!("ACME auth challenge completed"); + return Ok(()); + } + } + let target = { + let m = mapping.borrow(); + m.get(&target_name) + .into_iter() + .flatten() + .find(|(_, rc)| rc.strong_count() > 0) + .or_else(|| { + if target_name + .as_ref() + .map(|s| s.parse::().is_ok()) + .unwrap_or(true) + { + m.get(&None) + .into_iter() + .flatten() + .find(|(_, rc)| rc.strong_count() > 0) + } else { + None + } + }) + .map(|(target, _)| target.clone()) + }; + if let Some(target) = target { + if is_public && !target.public { + log::warn!( + "Rejecting connection from public interface to private bind: {bind} -> {target:?}" + ); + return Ok(()); + } + let peek = db.peek().await; + let root = peek + .as_private() + .as_key_store() + .as_local_certs() + .as_root_cert() + .de()?; + let mut cfg = async { + if let Some((domain, provider, settings)) = + target_name.as_ref().and_then(|domain| { + target.acme.as_ref().and_then(|a| { + peek.as_public() + .as_server_info() + .as_acme() + .as_idx(a) + .map(|s| (domain, a, s)) + }) + }) + { + let acme_settings = settings.de()?; + let mut identifiers = vec![Identifier::Dns(domain.to_string())]; + if false + // Requires RFC 8738 + { + if let Some(wan_ip) = wan_ip { + identifiers.push(Identifier::Ip(wan_ip.into())); } + } + let (send, recv) = watch::channel(None); + acme_tls_alpn_cache.mutate(|c| c.insert(domain.clone(), recv)); + let cert = async_acme::rustls_helper::order( + |_, cert| { + send.send_replace(Some(Arc::new(cert))); + Ok(()) + }, + provider.0.as_str(), + &identifiers, + Some(&AcmeCertCache(&db)), + &acme_settings.contact, + ) + .await + .with_kind(ErrorKind::OpenSsl)?; + return Ok(ServerConfig::builder_with_provider(crypto_provider.clone()) + .with_safe_default_protocol_versions() + .with_kind(crate::ErrorKind::OpenSsl)? + .with_no_client_auth() + .with_cert_resolver(Arc::new(SingleCertResolver(Arc::new(cert))))); + } + + let hostnames = target_name + .into_iter() + .chain([InternedString::from_display(&bind.ip())]) + .chain(wan_ip.as_ref().map(InternedString::from_display)) + .collect(); + let key = db + .mutate(|v| { + v.as_private_mut() + .as_key_store_mut() + .as_local_certs_mut() + .cert_for(&hostnames) + }) + .await?; + let cfg = ServerConfig::builder_with_provider(crypto_provider.clone()) + .with_safe_default_protocol_versions() + .with_kind(crate::ErrorKind::OpenSsl)? + .with_no_client_auth(); + if mid + .client_hello() + .signature_schemes() + .contains(&tokio_rustls::rustls::SignatureScheme::ED25519) + { + cfg.with_single_cert( + key.fullchain_ed25519() + .into_iter() + .map(|c| { + Ok(tokio_rustls::rustls::pki_types::CertificateDer::from( + c.to_der()?, + )) + }) + .collect::>()?, + PrivateKeyDer::from(PrivatePkcs8KeyDer::from( + key.leaf.keys.ed25519.private_key_to_pkcs8()?, + )), + ) + } else { + cfg.with_single_cert( + key.fullchain_nistp256() + .into_iter() + .map(|c| { + Ok(tokio_rustls::rustls::pki_types::CertificateDer::from( + c.to_der()?, + )) + }) + .collect::>()?, + PrivateKeyDer::from(PrivatePkcs8KeyDer::from( + key.leaf.keys.nistp256.private_key_to_pkcs8()?, + )), + ) + } + .with_kind(crate::ErrorKind::OpenSsl) + } + .await?; + let mut tcp_stream = TcpStream::connect(target.addr).await?; + match target.connect_ssl { + Ok(()) => { + let mut client_cfg = + tokio_rustls::rustls::ClientConfig::builder_with_provider(crypto_provider) + .with_safe_default_protocol_versions() + .with_kind(crate::ErrorKind::OpenSsl)? + .with_root_certificates({ + let mut store = RootCertStore::empty(); + store + .add(CertificateDer::from(root.to_der()?)) + .with_kind(crate::ErrorKind::OpenSsl)?; + store + }) + .with_no_client_auth(); + client_cfg.alpn_protocols = mid + .client_hello() + .alpn() + .into_iter() + .flatten() + .map(|x| x.to_vec()) + .collect(); + let mut target_stream = TlsConnector::from(Arc::new(client_cfg)) + .connect_with( + ServerName::IpAddress(target.addr.ip().into()), + tcp_stream, + |conn| { + cfg.alpn_protocols + .extend(conn.alpn_protocol().into_iter().map(|p| p.to_vec())) + }, + ) + .await + .with_kind(crate::ErrorKind::OpenSsl)?; + let mut accept = mid.into_stream(Arc::new(cfg)); + let io = accept.get_mut().unwrap(); + let buffered = io.stop_buffering(); + io.write_all(&buffered).await?; + let mut tls_stream = match accept.await { + Ok(a) => a, Err(e) => { tracing::trace!( - "VHostController: failed to accept connection on port {port}: {e}" + "VHostController: failed to accept TLS connection on {bind}: {e}" ); tracing::trace!("{e:?}"); + return Ok(()); } + }; + tokio::io::copy_bidirectional(&mut tls_stream, &mut target_stream).await + } + Err(AlpnInfo::Reflect) => { + for proto in mid.client_hello().alpn().into_iter().flatten() { + cfg.alpn_protocols.push(proto.into()); + } + let mut accept = mid.into_stream(Arc::new(cfg)); + let io = accept.get_mut().unwrap(); + let buffered = io.stop_buffering(); + io.write_all(&buffered).await?; + let mut tls_stream = match accept.await { + Ok(a) => a, + Err(e) => { + tracing::trace!( + "VHostController: failed to accept TLS connection on {bind}: {e}" + ); + tracing::trace!("{e:?}"); + return Ok(()); + } + }; + tokio::io::copy_bidirectional(&mut tls_stream, &mut tcp_stream).await + } + Err(AlpnInfo::Specified(alpn)) => { + cfg.alpn_protocols = alpn.into_iter().map(|a| a.0).collect(); + let mut accept = mid.into_stream(Arc::new(cfg)); + let io = accept.get_mut().unwrap(); + let buffered = io.stop_buffering(); + io.write_all(&buffered).await?; + let mut tls_stream = match accept.await { + Ok(a) => a, + Err(e) => { + tracing::trace!( + "VHostController: failed to accept TLS connection on {bind}: {e}" + ); + tracing::trace!("{e:?}"); + return Ok(()); + } + }; + tokio::io::copy_bidirectional(&mut tls_stream, &mut tcp_stream).await + } + } + .map_or_else( + |e| { + use std::io::ErrorKind as E; + match e.kind() { + E::UnexpectedEof + | E::BrokenPipe + | E::ConnectionAborted + | E::ConnectionReset + | E::ConnectionRefused + | E::TimedOut + | E::Interrupted + | E::NotConnected => Ok(()), + _ => Err(e), + } + }, + |_| Ok(()), + )?; + } else { + // 503 + } + Ok::<_, Error>(()) + } + + #[instrument(skip_all)] + fn new( + port: u16, + db: TypedPatchDb, + iface_ctrl: Arc, + crypto_provider: Arc, + acme_tls_alpn_cache: AcmeTlsAlpnCache, + ) -> Result { + let mut listener = iface_ctrl.bind(port).with_kind(crate::ErrorKind::Network)?; + let (map_send, map_recv) = watch::channel(BTreeMap::new()); + Ok(Self { + mapping: map_send, + _thread: tokio::spawn(async move { + loop { + if let Err(e) = Self::accept( + &mut listener, + map_recv.clone(), + db.clone(), + acme_tls_alpn_cache.clone(), + crypto_provider.clone(), + ) + .await + { + tracing::error!( + "VHostController: failed to accept connection on {port}: {e}" + ); + tracing::debug!("{e:?}"); } } }) .into(), }) } - async fn add( - &self, - hostname: Option, - target: TargetInfo, - ) -> Result, Error> { - if let Some(mapping) = Weak::upgrade(&self.mapping) { - let mut writable = mapping.write().await; + fn add(&self, hostname: Option, target: TargetInfo) -> Result, Error> { + let mut res = Ok(Arc::new(())); + self.mapping.send_if_modified(|writable| { + let mut changed = false; let mut targets = writable.remove(&hostname).unwrap_or_default(); let rc = if let Some(rc) = Weak::upgrade(&targets.remove(&target).unwrap_or_default()) { rc } else { + changed = true; Arc::new(()) }; targets.insert(target, Arc::downgrade(&rc)); writable.insert(hostname, targets); - Ok(rc) + res = Ok(rc); + changed + }); + if !self.mapping.is_closed() { + res } else { Err(Error::new( eyre!("VHost Service Thread has exited"), @@ -546,33 +714,22 @@ impl VHostServer { )) } } - async fn gc(&self, hostname: Option) -> Result<(), Error> { - if let Some(mapping) = Weak::upgrade(&self.mapping) { - let mut writable = mapping.write().await; + fn gc(&self, hostname: Option) { + self.mapping.send_if_modified(|writable| { let mut targets = writable.remove(&hostname).unwrap_or_default(); + let pre = targets.len(); targets = targets .into_iter() .filter(|(_, rc)| rc.strong_count() > 0) .collect(); + let post = targets.len(); if !targets.is_empty() { writable.insert(hostname, targets); } - Ok(()) - } else { - Err(Error::new( - eyre!("VHost Service Thread has exited"), - crate::ErrorKind::Network, - )) - } + pre == post + }); } - async fn is_empty(&self) -> Result { - if let Some(mapping) = Weak::upgrade(&self.mapping) { - Ok(mapping.read().await.is_empty()) - } else { - Err(Error::new( - eyre!("VHost Service Thread has exited"), - crate::ErrorKind::Network, - )) - } + fn is_empty(&self) -> bool { + self.mapping.borrow().is_empty() } } diff --git a/core/startos/src/net/web_server.rs b/core/startos/src/net/web_server.rs index d1ad64d01..b38a7ee56 100644 --- a/core/startos/src/net/web_server.rs +++ b/core/startos/src/net/web_server.rs @@ -1,134 +1,299 @@ -use std::convert::Infallible; +use std::future::Future; use std::net::SocketAddr; +use std::ops::Deref; +use std::sync::atomic::AtomicBool; +use std::sync::{Arc, RwLock}; use std::task::Poll; use std::time::Duration; -use axum::extract::Request; use axum::Router; -use axum_server::Handle; -use bytes::Bytes; -use futures::future::{ready, BoxFuture}; +use futures::future::{BoxFuture, Either}; use futures::FutureExt; use helpers::NonDetachingJoinHandle; +use hyper_util::rt::{TokioIo, TokioTimer}; +use hyper_util::service::TowerToHyperService; +use tokio::net::{TcpListener, TcpStream}; use tokio::sync::{oneshot, watch}; use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext}; +use crate::net::network_interface::NetworkInterfaceListener; use crate::net::static_server::{ - diagnostic_ui_router, init_ui_router, install_ui_router, main_ui_router, refresher, + diagnostic_ui_router, init_ui_router, install_ui_router, main_ui_router, redirecter, refresher, setup_ui_router, }; use crate::prelude::*; +use crate::util::actor::background::BackgroundJobQueue; -#[derive(Clone)] -pub struct SwappableRouter(watch::Sender); -impl SwappableRouter { - pub fn new(router: Router) -> Self { - Self(watch::channel(router).0) - } - pub fn swap(&self, router: Router) { - let _ = self.0.send_replace(router); - } +pub struct Accepted { + pub https_redirect: bool, + pub stream: TcpStream, } -pub struct SwappableRouterService { - router: watch::Receiver, - changed: Option>, +pub trait Accept { + fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll>; } -impl SwappableRouterService { - fn router(&self) -> Router { - self.router.borrow().clone() - } - fn changed(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> { - let mut changed = if let Some(changed) = self.changed.take() { - changed - } else { - let mut router = self.router.clone(); - async move { - router.changed().await; + +impl Accept for Vec { + fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { + for listener in &*self { + if let Poll::Ready((stream, _)) = listener.poll_accept(cx)? { + return Poll::Ready(Ok(Accepted { + https_redirect: false, + stream, + })); } - .boxed() - }; - if changed.poll_unpin(cx).is_ready() { - return Poll::Ready(()); } - self.changed = Some(changed); Poll::Pending } } -impl Clone for SwappableRouterService { - fn clone(&self) -> Self { +impl Accept for NetworkInterfaceListener { + fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { + NetworkInterfaceListener::poll_accept(self, cx, true).map(|res| { + res.map(|a| Accepted { + https_redirect: a.is_public, + stream: a.stream, + }) + }) + } +} + +impl Accept for Either { + fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { + match self { + Either::Left(a) => a.poll_accept(cx), + Either::Right(b) => b.poll_accept(cx), + } + } +} +impl Accept for Option { + fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { + match self { + None => Poll::Pending, + Some(a) => a.poll_accept(cx), + } + } +} + +#[pin_project::pin_project] +pub struct Acceptor { + acceptor: (watch::Sender, watch::Receiver), + changed: Option>, +} +impl Acceptor { + pub fn new(acceptor: A) -> Self { Self { - router: self.router.clone(), + acceptor: watch::channel(acceptor), changed: None, } } -} -impl tower_service::Service> for SwappableRouterService -where - B: axum::body::HttpBody + Send + 'static, - B::Error: Into, -{ - type Response = >>::Response; - type Error = >>::Error; - type Future = >>::Future; - #[inline] - fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { - if self.changed(cx).is_ready() { - return Poll::Ready(Ok(())); + + fn poll_changed(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> { + let mut changed = if let Some(changed) = self.changed.take() { + changed + } else { + let mut recv = self.acceptor.1.clone(); + async move { + let _ = recv.changed().await; + } + .boxed() + }; + let res = changed.poll_unpin(cx); + if res.is_pending() { + self.changed = Some(changed); } - tower_service::Service::>::poll_ready(&mut self.router(), cx) + res } - fn call(&mut self, req: Request) -> Self::Future { - self.router().call(req) + + fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { + let _ = self.poll_changed(cx); + let mut res = Poll::Pending; + self.acceptor.0.send_if_modified(|a| { + res = a.poll_accept(cx); + false + }); + res + } + + async fn accept(&mut self) -> Result { + std::future::poll_fn(|cx| self.poll_accept(cx)).await + } +} +impl Acceptor> { + pub async fn bind(listen: impl IntoIterator) -> Result { + Ok(Self::new( + futures::future::try_join_all(listen.into_iter().map(TcpListener::bind)).await?, + )) } } -impl tower_service::Service for SwappableRouter { - type Response = SwappableRouterService; - type Error = Infallible; - type Future = futures::future::Ready>; - #[inline] - fn poll_ready( - &mut self, - _: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - Poll::Ready(Ok(())) - } - fn call(&mut self, _: T) -> Self::Future { - ready(Ok(SwappableRouterService { - router: self.0.subscribe(), - changed: None, - })) +pub type UpgradableListener = Option, NetworkInterfaceListener>>; + +impl Acceptor { + pub async fn bind_upgradable( + listen: impl IntoIterator, + ) -> Result { + Ok(Self::new(Some(Either::Left( + futures::future::try_join_all(listen.into_iter().map(TcpListener::bind)).await?, + )))) } } -pub struct WebServer { +pub struct WebServerAcceptorSetter { + acceptor: watch::Sender, +} +impl WebServerAcceptorSetter>> { + pub fn try_upgrade Result>(&self, f: F) -> Result<(), Error> { + let mut res = Ok(()); + self.acceptor.send_modify(|a| { + *a = match a.take() { + Some(Either::Left(a)) => match f(a) { + Ok(b) => Some(Either::Right(b)), + Err(e) => { + res = Err(e); + None + } + }, + x => x, + } + }); + res + } +} +impl Deref for WebServerAcceptorSetter { + type Target = watch::Sender; + fn deref(&self) -> &Self::Target { + &self.acceptor + } +} + +pub struct WebServer { shutdown: oneshot::Sender<()>, - router: SwappableRouter, + router: watch::Sender>, + acceptor: watch::Sender, thread: NonDetachingJoinHandle<()>, } -impl WebServer { - pub fn new(bind: SocketAddr) -> Self { - let router = SwappableRouter::new(refresher()); - let thread_router = router.clone(); +impl WebServer { + pub fn acceptor_setter(&self) -> WebServerAcceptorSetter { + WebServerAcceptorSetter { + acceptor: self.acceptor.clone(), + } + } + + pub fn new(mut acceptor: Acceptor) -> Self { + let acceptor_send = acceptor.acceptor.0.clone(); + let (router, service) = watch::channel::>(None); let (shutdown, shutdown_recv) = oneshot::channel(); let thread = NonDetachingJoinHandle::from(tokio::spawn(async move { - let handle = Handle::new(); - let mut server = axum_server::bind(bind).handle(handle.clone()); - server.http_builder().http1().preserve_header_case(true); - server.http_builder().http1().title_case_headers(true); + #[derive(Clone)] + struct QueueRunner { + queue: Arc>>, + } + impl hyper::rt::Executor for QueueRunner + where + Fut: Future + Send + 'static, + { + fn execute(&self, fut: Fut) { + if let Some(q) = &*self.queue.read().unwrap() { + q.add_job(fut); + } else { + tracing::warn!("job queued after shutdown"); + } + } + } - if let (Err(e), _) = tokio::join!(server.serve(thread_router), async { - let _ = shutdown_recv.await; - handle.graceful_shutdown(Some(Duration::from_secs(0))); - }) { - tracing::error!("Spawning hyper server error: {}", e); + let accept = AtomicBool::new(true); + let queue_cell = Arc::new(RwLock::new(None)); + let graceful = hyper_util::server::graceful::GracefulShutdown::new(); + let mut server = hyper_util::server::conn::auto::Builder::new(QueueRunner { + queue: queue_cell.clone(), + }); + server + .http1() + .timer(TokioTimer::new()) + .title_case_headers(true) + .preserve_header_case(true) + .http2() + .timer(TokioTimer::new()) + .enable_connect_protocol() + .keep_alive_interval(Duration::from_secs(60)) + .keep_alive_timeout(Duration::from_secs(300)); + let (queue, mut runner) = BackgroundJobQueue::new(); + *queue_cell.write().unwrap() = Some(queue.clone()); + + let handler = async { + loop { + if let Err(e) = async { + let accepted = acceptor.accept().await?; + if accepted.https_redirect { + queue.add_job( + graceful.watch( + server + .serve_connection_with_upgrades( + TokioIo::new(accepted.stream), + TowerToHyperService::new(redirecter().into_service()), + ) + .into_owned(), + ), + ); + } else { + let service = { service.borrow().clone() }; + if let Some(service) = service { + queue.add_job( + graceful.watch( + server + .serve_connection_with_upgrades( + TokioIo::new(accepted.stream), + TowerToHyperService::new(service.into_service()), + ) + .into_owned(), + ), + ); + } else { + queue.add_job( + graceful.watch( + server + .serve_connection_with_upgrades( + TokioIo::new(accepted.stream), + TowerToHyperService::new( + refresher().into_service(), + ), + ) + .into_owned(), + ), + ); + } + } + + Ok::<_, Error>(()) + } + .await + { + tracing::error!("Error accepting HTTP connection: {e}"); + tracing::debug!("{e:?}"); + } + } + } + .boxed(); + + tokio::select! { + _ = shutdown_recv => (), + _ = handler => (), + _ = &mut runner => (), + } + + accept.store(false, std::sync::atomic::Ordering::SeqCst); + drop(queue); + drop(queue_cell.write().unwrap().take()); + + if !runner.is_empty() { + runner.await; } })); Self { shutdown, router, thread, + acceptor: acceptor_send, } } @@ -138,7 +303,7 @@ impl WebServer { } pub fn serve_router(&mut self, router: Router) { - self.router.swap(router) + self.router.send_replace(Some(router)); } pub fn serve_main(&mut self, ctx: RpcContext) { diff --git a/core/startos/src/net/wifi.rs b/core/startos/src/net/wifi.rs index 056a403de..b2e59c20f 100644 --- a/core/startos/src/net/wifi.rs +++ b/core/startos/src/net/wifi.rs @@ -298,7 +298,7 @@ fn display_wifi_info(params: WithIoFormat, info: WifiListInfo) { let mut table_global = Table::new(); table_global.add_row(row![bc => "CONNECTED", - "SIGNAL_STRENGTH", + "SIGNAL STRENGTH", "COUNTRY", "ETHERNET", ]); @@ -306,12 +306,12 @@ fn display_wifi_info(params: WithIoFormat, info: WifiListInfo) { &info .connected .as_ref() - .map_or("[N/A]".to_owned(), |c| c.0.clone()), + .map_or("N/A".to_owned(), |c| c.0.clone()), &info .connected .as_ref() .and_then(|x| info.ssids.get(x)) - .map_or("[N/A]".to_owned(), |ss| format!("{}", ss.0)), + .map_or("N/A".to_owned(), |ss| format!("{}", ss.0)), info.country.as_ref().map(|c| c.alpha2()).unwrap_or("00"), &format!("{}", info.ethernet) ]); @@ -897,32 +897,29 @@ impl TypedValueParser for CountryCodeParser { } #[instrument(skip_all)] -pub async fn synchronize_wpa_supplicant_conf>( +pub async fn synchronize_network_manager>( main_datadir: P, wifi: &mut WifiInfo, ) -> Result<(), Error> { wifi.interface = find_wifi_iface().await?; - let Some(wifi_iface) = &wifi.interface else { - return Ok(()); - }; let persistent = main_datadir.as_ref().join("system-connections"); - tracing::debug!("persistent: {:?}", persistent); - // let supplicant = Path::new("/etc/wpa_supplicant.conf"); if tokio::fs::metadata(&persistent).await.is_err() { tokio::fs::create_dir_all(&persistent).await?; } crate::disk::mount::util::bind(&persistent, "/etc/NetworkManager/system-connections", false) .await?; - // if tokio::fs::metadata(&supplicant).await.is_err() { - // tokio::fs::write(&supplicant, include_str!("wpa_supplicant.conf.base")).await?; - // } Command::new("systemctl") .arg("restart") .arg("NetworkManager") .invoke(ErrorKind::Wifi) .await?; + + let Some(wifi_iface) = &wifi.interface else { + return Ok(()); + }; + Command::new("ifconfig") .arg(wifi_iface) .arg("up") diff --git a/core/startos/src/os_install/gpt.rs b/core/startos/src/os_install/gpt.rs index 01703083b..4833f4ea7 100644 --- a/core/startos/src/os_install/gpt.rs +++ b/core/startos/src/os_install/gpt.rs @@ -50,7 +50,7 @@ pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result {{ + tracing::debug!("[{}:{}:{}]", file!(), line!(), column!()); + }}; + ($e:expr) => {{ + let e = $e; + tracing::debug!("[{}:{}:{}] {} = {e:?}", file!(), line!(), column!(), stringify!($e)); + e + }}; + ($($e:expr),+) => { + ($( + crate::dbg!($e) + ),+) + } +} diff --git a/core/startos/src/registry/context.rs b/core/startos/src/registry/context.rs index 16c6465ed..d78fde50e 100644 --- a/core/startos/src/registry/context.rs +++ b/core/startos/src/registry/context.rs @@ -19,7 +19,6 @@ use crate::context::config::{ContextConfig, CONFIG_PATH}; use crate::context::{CliContext, RpcContext}; use crate::prelude::*; use crate::registry::auth::{SignatureHeader, AUTH_SIG_HEADER}; -use crate::registry::device_info::{DeviceInfo, DEVICE_INFO_HEADER}; use crate::registry::signer::sign::AnySigningKey; use crate::registry::RegistryDatabase; use crate::rpc_continuations::RpcContinuations; diff --git a/core/startos/src/registry/mod.rs b/core/startos/src/registry/mod.rs index 0cbbce4e0..4e1411ea9 100644 --- a/core/startos/src/registry/mod.rs +++ b/core/startos/src/registry/mod.rs @@ -2,7 +2,6 @@ use std::collections::{BTreeMap, BTreeSet}; use axum::Router; use futures::future::ready; -use imbl_value::InternedString; use models::DataUrl; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler, Server}; use serde::{Deserialize, Serialize}; @@ -11,13 +10,13 @@ use ts_rs::TS; use crate::context::CliContext; use crate::middleware::cors::Cors; use crate::net::static_server::{bad_request, not_found, server_error}; -use crate::net::web_server::WebServer; +use crate::net::web_server::{Accept, WebServer}; use crate::prelude::*; use crate::registry::auth::Auth; use crate::registry::context::RegistryContext; use crate::registry::device_info::DeviceInfoMiddleware; use crate::registry::os::index::OsIndex; -use crate::registry::package::index::{Category, PackageIndex}; +use crate::registry::package::index::PackageIndex; use crate::registry::signer::SignerInfo; use crate::rpc_continuations::Guid; use crate::util::serde::HandlerExtSerde; @@ -144,7 +143,7 @@ pub fn registry_router(ctx: RegistryContext) -> Router { ) } -impl WebServer { +impl WebServer { pub fn serve_registry(&mut self, ctx: RegistryContext) { self.serve_router(registry_router(ctx)) } diff --git a/core/startos/src/registry/package/index.rs b/core/startos/src/registry/package/index.rs index 428200165..9973bae7e 100644 --- a/core/startos/src/registry/package/index.rs +++ b/core/startos/src/registry/package/index.rs @@ -72,7 +72,6 @@ pub struct PackageVersionInfo { pub icon: DataUrl<'static>, pub description: Description, pub release_notes: String, - #[ts(type = "string")] pub git_hash: GitHash, #[ts(type = "string")] pub license: InternedString, diff --git a/core/startos/src/registry/signer/commitment/merkle_archive.rs b/core/startos/src/registry/signer/commitment/merkle_archive.rs index 1b9d7d1e0..b27fb7ef4 100644 --- a/core/startos/src/registry/signer/commitment/merkle_archive.rs +++ b/core/startos/src/registry/signer/commitment/merkle_archive.rs @@ -24,10 +24,10 @@ impl MerkleArchiveCommitment { pub fn from_query(query: &str) -> Result, Error> { let mut root_sighash = None; let mut root_maxsize = None; - for (k, v) in form_urlencoded::parse(dbg!(query).as_bytes()) { + for (k, v) in form_urlencoded::parse(query.as_bytes()) { match &*k { "rootSighash" => { - root_sighash = Some(dbg!(v).parse()?); + root_sighash = Some(v.parse()?); } "rootMaxsize" => { root_maxsize = Some(v.parse()?); diff --git a/core/startos/src/s9pk/git_hash.rs b/core/startos/src/s9pk/git_hash.rs index 02f83bf4a..762ef8704 100644 --- a/core/startos/src/s9pk/git_hash.rs +++ b/core/startos/src/s9pk/git_hash.rs @@ -1,11 +1,13 @@ use std::path::Path; use tokio::process::Command; +use ts_rs::TS; use crate::prelude::*; use crate::util::Invoke; -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, TS)] +#[ts(type = "string")] pub struct GitHash(String); impl GitHash { @@ -31,6 +33,31 @@ impl GitHash { } Ok(GitHash(hash)) } + pub fn load_sync() -> Option { + let mut hash = String::from_utf8( + std::process::Command::new("git") + .arg("rev-parse") + .arg("HEAD") + .output() + .ok()? + .stdout, + ) + .ok()?; + if !std::process::Command::new("git") + .arg("diff-index") + .arg("--quiet") + .arg("HEAD") + .arg("--") + .output() + .ok()? + .status + .success() + { + hash += "-modified"; + } + + Some(GitHash(hash)) + } } impl AsRef for GitHash { diff --git a/core/startos/src/s9pk/v2/manifest.rs b/core/startos/src/s9pk/v2/manifest.rs index 85f3cd796..11ea0d9af 100644 --- a/core/startos/src/s9pk/v2/manifest.rs +++ b/core/startos/src/s9pk/v2/manifest.rs @@ -3,7 +3,6 @@ use std::path::Path; use color_eyre::eyre::eyre; use exver::{Version, VersionRange}; -use helpers::const_true; use imbl_value::InternedString; pub use models::PackageId; use models::{mime, ImageId, VolumeId}; @@ -62,8 +61,8 @@ pub struct Manifest { pub dependencies: Dependencies, #[serde(default)] pub hardware_requirements: HardwareRequirements, - #[serde(default)] - #[ts(type = "string | null")] + #[ts(optional)] + #[serde(default = "GitHash::load_sync")] pub git_hash: Option, #[serde(default = "current_version")] #[ts(type = "string")] diff --git a/core/startos/src/service/effects/callbacks.rs b/core/startos/src/service/effects/callbacks.rs index 65eb707d8..19946672c 100644 --- a/core/startos/src/service/effects/callbacks.rs +++ b/core/startos/src/service/effects/callbacks.rs @@ -294,7 +294,7 @@ impl CallbackHandler { } } pub async fn call(mut self, args: Vector) -> Result<(), Error> { - dbg!(eyre!("callback fired: {}", self.handle.is_active())); + crate::dbg!(eyre!("callback fired: {}", self.handle.is_active())); if let Some(seed) = self.seed.upgrade() { seed.persistent_container .callback(self.handle.take(), args) diff --git a/core/startos/src/service/effects/dependency.rs b/core/startos/src/service/effects/dependency.rs index ed43b7a9c..2a16b4155 100644 --- a/core/startos/src/service/effects/dependency.rs +++ b/core/startos/src/service/effects/dependency.rs @@ -17,11 +17,11 @@ use crate::db::model::package::{ use crate::disk::mount::filesystem::bind::Bind; use crate::disk::mount::filesystem::idmapped::IdMapped; use crate::disk::mount::filesystem::{FileSystem, MountType}; -use crate::rpc_continuations::Guid; use crate::service::effects::prelude::*; use crate::status::health_check::NamedHealthCheckResult; use crate::util::Invoke; use crate::volume::data_dir; +use crate::DATA_DIR; #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[ts(export)] @@ -55,7 +55,7 @@ pub async fn mount( let context = context.deref()?; let subpath = subpath.unwrap_or_default(); let subpath = subpath.strip_prefix("/").unwrap_or(&subpath); - let source = data_dir(&context.seed.ctx.datadir, &package_id, &volume_id).join(subpath); + let source = data_dir(DATA_DIR, &package_id, &volume_id).join(subpath); if tokio::fs::metadata(&source).await.is_err() { tokio::fs::create_dir_all(&source).await?; } diff --git a/core/startos/src/service/effects/mod.rs b/core/startos/src/service/effects/mod.rs index f68985268..e9df6f9f2 100644 --- a/core/startos/src/service/effects/mod.rs +++ b/core/startos/src/service/effects/mod.rs @@ -130,10 +130,6 @@ pub fn handler() -> ParentHandler { "get-host-info", from_fn_async(net::host::get_host_info).no_cli(), ) - .subcommand( - "get-primary-url", - from_fn_async(net::host::get_primary_url).no_cli(), - ) .subcommand( "get-container-ip", from_fn_async(net::info::get_container_ip).no_cli(), diff --git a/core/startos/src/service/effects/net/bind.rs b/core/startos/src/service/effects/net/bind.rs index 5619375eb..2f3edb07b 100644 --- a/core/startos/src/service/effects/net/bind.rs +++ b/core/startos/src/service/effects/net/bind.rs @@ -1,6 +1,6 @@ use models::{HostId, PackageId}; -use crate::net::host::binding::{BindId, BindOptions, LanInfo}; +use crate::net::host::binding::{BindId, BindOptions, NetInfo}; use crate::net::host::HostKind; use crate::service::effects::prelude::*; @@ -53,15 +53,36 @@ pub struct GetServicePortForwardParams { #[ts(optional)] package_id: Option, host_id: HostId, - internal_port: u32, + internal_port: u16, } pub async fn get_service_port_forward( context: EffectContext, - data: GetServicePortForwardParams, -) -> Result { - let internal_port = data.internal_port as u16; - + GetServicePortForwardParams { + package_id, + host_id, + internal_port, + }: GetServicePortForwardParams, +) -> Result { let context = context.deref()?; - let net_service = context.seed.persistent_container.net_service.lock().await; - net_service.get_lan_port(data.host_id, internal_port) + + let package_id = package_id.unwrap_or_else(|| context.seed.id.clone()); + + Ok(context + .seed + .ctx + .db + .peek() + .await + .as_public() + .as_package_data() + .as_idx(&package_id) + .or_not_found(&package_id)? + .as_hosts() + .as_idx(&host_id) + .or_not_found(&host_id)? + .as_bindings() + .de()? + .get(&internal_port) + .or_not_found(lazy_format!("binding for port {internal_port}"))? + .net) } diff --git a/core/startos/src/service/effects/net/host.rs b/core/startos/src/service/effects/net/host.rs index d320e7fe9..570d5033d 100644 --- a/core/startos/src/service/effects/net/host.rs +++ b/core/startos/src/service/effects/net/host.rs @@ -1,35 +1,10 @@ use models::{HostId, PackageId}; -use crate::net::host::address::HostAddress; use crate::net::host::Host; use crate::service::effects::callbacks::CallbackHandler; use crate::service::effects::prelude::*; use crate::service::rpc::CallbackId; -#[derive(Debug, Clone, Serialize, Deserialize, TS)] -#[ts(export)] -#[serde(rename_all = "camelCase")] -pub struct GetPrimaryUrlParams { - #[ts(optional)] - package_id: Option, - host_id: HostId, - #[ts(optional)] - callback: Option, -} -pub async fn get_primary_url( - context: EffectContext, - GetPrimaryUrlParams { - package_id, - host_id, - callback, - }: GetPrimaryUrlParams, -) -> Result, Error> { - let context = context.deref()?; - let package_id = package_id.unwrap_or_else(|| context.seed.id.clone()); - - Ok(None) // TODO -} - #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export)] diff --git a/core/startos/src/service/effects/net/interface.rs b/core/startos/src/service/effects/net/interface.rs index 44258c36a..5de9638c4 100644 --- a/core/startos/src/service/effects/net/interface.rs +++ b/core/startos/src/service/effects/net/interface.rs @@ -15,7 +15,6 @@ pub struct ExportServiceInterfaceParams { id: ServiceInterfaceId, name: String, description: String, - has_primary: bool, masked: bool, address_info: AddressInfo, r#type: ServiceInterfaceType, @@ -26,7 +25,6 @@ pub async fn export_service_interface( id, name, description, - has_primary, masked, address_info, r#type, @@ -39,7 +37,6 @@ pub async fn export_service_interface( id: id.clone(), name, description, - has_primary, masked, address_info, interface_type: r#type, diff --git a/core/startos/src/service/effects/net/ssl.rs b/core/startos/src/service/effects/net/ssl.rs index d37a2d241..66b4fa1e6 100644 --- a/core/startos/src/service/effects/net/ssl.rs +++ b/core/startos/src/service/effects/net/ssl.rs @@ -51,10 +51,16 @@ pub async fn get_ssl_certificate( .iter() .map(|(_, m)| m.as_hosts().as_entries()) .flatten_ok() - .map_ok(|(_, m)| m.as_addresses().de()) + .map_ok(|(_, m)| { + Ok(m.as_onions() + .de()? + .iter() + .map(InternedString::from_display) + .chain(m.as_domains().keys()?) + .collect::>()) + }) .map(|a| a.and_then(|a| a)) .flatten_ok() - .map_ok(|a| InternedString::from_display(&a)) .try_collect::<_, BTreeSet<_>, _>()?; for hostname in &hostnames { if let Some(internal) = hostname @@ -135,10 +141,16 @@ pub async fn get_ssl_key( .into_iter() .map(|m| m.as_hosts().as_entries()) .flatten_ok() - .map_ok(|(_, m)| m.as_addresses().de()) + .map_ok(|(_, m)| { + Ok(m.as_onions() + .de()? + .iter() + .map(InternedString::from_display) + .chain(m.as_domains().keys()?) + .collect::>()) + }) .map(|a| a.and_then(|a| a)) .flatten_ok() - .map_ok(|a| InternedString::from_display(&a)) .try_collect::<_, BTreeSet<_>, _>()?; for hostname in &hostnames { if let Some(internal) = hostname diff --git a/core/startos/src/service/effects/store.rs b/core/startos/src/service/effects/store.rs index 1d4a07086..39166c333 100644 --- a/core/startos/src/service/effects/store.rs +++ b/core/startos/src/service/effects/store.rs @@ -26,7 +26,7 @@ pub async fn get_store( callback, }: GetStoreParams, ) -> Result { - dbg!(&callback); + crate::dbg!(&callback); let context = context.deref()?; let peeked = context.seed.ctx.db.peek().await; let package_id = package_id.unwrap_or(context.seed.id.clone()); diff --git a/core/startos/src/service/mod.rs b/core/startos/src/service/mod.rs index d73c51beb..5bc7fd999 100644 --- a/core/startos/src/service/mod.rs +++ b/core/startos/src/service/mod.rs @@ -48,7 +48,7 @@ use crate::util::net::WebSocketExt; use crate::util::serde::{NoOutput, Pem}; use crate::util::Never; use crate::volume::data_dir; -use crate::CAP_1_KiB; +use crate::{CAP_1_KiB, DATA_DIR, PACKAGE_DATA}; pub mod action; pub mod cli; @@ -149,10 +149,10 @@ impl ServiceRef { .values() .flat_map(|h| h.bindings.values()) .flat_map(|b| { - b.lan + b.net .assigned_port .into_iter() - .chain(b.lan.assigned_ssl_port) + .chain(b.net.assigned_ssl_port) }), ); Ok(()) @@ -167,17 +167,18 @@ impl ServiceRef { { let state = pde.state_info.expect_removing()?; for volume_id in &state.manifest.volumes { - let path = data_dir(&ctx.datadir, &state.manifest.id, volume_id); + let path = data_dir(DATA_DIR, &state.manifest.id, volume_id); if tokio::fs::metadata(&path).await.is_ok() { tokio::fs::remove_dir_all(&path).await?; } } - let logs_dir = ctx.datadir.join("logs").join(&state.manifest.id); + let logs_dir = Path::new(PACKAGE_DATA) + .join("logs") + .join(&state.manifest.id); if tokio::fs::metadata(&logs_dir).await.is_ok() { tokio::fs::remove_dir_all(&logs_dir).await?; } - let archive_path = ctx - .datadir + let archive_path = Path::new(PACKAGE_DATA) .join("archive") .join("installed") .join(&state.manifest.id); @@ -278,7 +279,7 @@ impl Service { let ctx = ctx.clone(); move |s9pk: S9pk, i: Model| async move { for volume_id in &s9pk.as_manifest().volumes { - let path = data_dir(&ctx.datadir, &s9pk.as_manifest().id, volume_id); + let path = data_dir(DATA_DIR, &s9pk.as_manifest().id, volume_id); if tokio::fs::metadata(&path).await.is_err() { tokio::fs::create_dir_all(&path).await?; } @@ -291,7 +292,7 @@ impl Service { Self::new(ctx, s9pk, start_stop).await.map(Some) } }; - let s9pk_dir = ctx.datadir.join(PKG_ARCHIVE_DIR).join("installed"); // TODO: make this based on hash + let s9pk_dir = Path::new(DATA_DIR).join(PKG_ARCHIVE_DIR).join("installed"); // TODO: make this based on hash let s9pk_path = s9pk_dir.join(id).with_extension("s9pk"); let Some(entry) = ctx .db @@ -605,6 +606,7 @@ impl Service { } pub async fn update_host(&self, host_id: HostId) -> Result<(), Error> { + let mut service = self.seed.persistent_container.net_service.lock().await; let host = self .seed .ctx @@ -619,13 +621,7 @@ impl Service { .as_idx(&host_id) .or_not_found(&host_id)? .de()?; - self.seed - .persistent_container - .net_service - .lock() - .await - .update(host_id, host) - .await + service.update(host_id, host).await } } @@ -934,7 +930,6 @@ pub async fn attach( .with_kind(ErrorKind::Network)?; current_out = "stdout"; } - dbg!(¤t_out); ws.send(Message::Binary(out)) .await .with_kind(ErrorKind::Network)?; @@ -948,7 +943,6 @@ pub async fn attach( .with_kind(ErrorKind::Network)?; current_out = "stderr"; } - dbg!(¤t_out); ws.send(Message::Binary(err)) .await .with_kind(ErrorKind::Network)?; diff --git a/core/startos/src/service/persistent_container.rs b/core/startos/src/service/persistent_container.rs index 13cb7688c..d99d9bb49 100644 --- a/core/startos/src/service/persistent_container.rs +++ b/core/startos/src/service/persistent_container.rs @@ -39,7 +39,7 @@ use crate::util::io::create_file; use crate::util::rpc_client::UnixRpcClient; use crate::util::Invoke; use crate::volume::data_dir; -use crate::ARCH; +use crate::{ARCH, DATA_DIR, PACKAGE_DATA}; const RPC_CONNECT_TIMEOUT: Duration = Duration::from_secs(10); @@ -121,8 +121,8 @@ impl PersistentContainer { .lxc_manager .create( Some( - &ctx.datadir - .join("package-data/logs") + &Path::new(PACKAGE_DATA) + .join("logs") .join(&s9pk.as_manifest().id), ), LxcConfig::default(), @@ -157,7 +157,7 @@ impl PersistentContainer { .await?; let mount = MountGuard::mount( &IdMapped::new( - Bind::new(data_dir(&ctx.datadir, &s9pk.as_manifest().id, volume)), + Bind::new(data_dir(DATA_DIR, &s9pk.as_manifest().id, volume)), 0, 100000, 65536, @@ -452,7 +452,7 @@ impl PersistentContainer { #[instrument(skip_all)] pub async fn exit(mut self) -> Result<(), Error> { if let Some(destroy) = self.destroy(false) { - dbg!(destroy.await)?; + destroy.await?; } tracing::info!("Service for {} exited", self.s9pk.as_manifest().id); diff --git a/core/startos/src/service/rpc.rs b/core/startos/src/service/rpc.rs index f008de5c7..61eb5d592 100644 --- a/core/startos/src/service/rpc.rs +++ b/core/startos/src/service/rpc.rs @@ -155,7 +155,7 @@ impl serde::Serialize for Sandbox { pub struct CallbackId(u64); impl CallbackId { pub fn register(self, container: &PersistentContainer) -> CallbackHandle { - dbg!(eyre!( + crate::dbg!(eyre!( "callback {} registered for {}", self.0, container.s9pk.as_manifest().id diff --git a/core/startos/src/service/service_actor.rs b/core/startos/src/service/service_actor.rs index 712baaf1e..b88136650 100644 --- a/core/startos/src/service/service_actor.rs +++ b/core/startos/src/service/service_actor.rs @@ -36,7 +36,41 @@ impl Actor for ServiceActor { ServiceActorLoopNext::DontWait => (), } } - }) + }); + let seed = self.0.clone(); + let mut ip_info = seed.ctx.net_controller.net_iface.subscribe(); + jobs.add_job(async move { + loop { + if let Err(e) = async { + let mut service = seed.persistent_container.net_service.lock().await; + let hosts = seed + .ctx + .db + .peek() + .await + .as_public() + .as_package_data() + .as_idx(&seed.id) + .or_not_found(&seed.id)? + .as_hosts() + .de()?; + for (host_id, host) in hosts.0 { + service.update(host_id, host).await?; + } + + Ok::<_, Error>(()) + } + .await + { + tracing::error!("Error syncronizing net host after network change: {e}"); + tracing::debug!("{e:?}"); + } + + if ip_info.changed().await.is_err() { + break; + }; + } + }); } } @@ -92,7 +126,6 @@ async fn service_actor_loop( .. } => MainStatus::Stopped, }; - let previous = i.as_status().de()?; i.as_status_mut().ser(&main_status)?; return Ok(previous .major_changes(&main_status) diff --git a/core/startos/src/service/service_map.rs b/core/startos/src/service/service_map.rs index 0faab8dd5..104e191ba 100644 --- a/core/startos/src/service/service_map.rs +++ b/core/startos/src/service/service_map.rs @@ -1,3 +1,4 @@ +use std::path::Path; use std::sync::Arc; use std::time::Duration; @@ -27,6 +28,7 @@ use crate::service::start_stop::StartStop; use crate::service::{LoadDisposition, Service, ServiceRef}; use crate::status::MainStatus; use crate::util::serde::Pem; +use crate::DATA_DIR; pub type DownloadInstallFuture = BoxFuture<'static, Result>; pub type InstallFuture = BoxFuture<'static, Result<(), Error>>; @@ -220,8 +222,7 @@ impl ServiceMap { Ok(async move { let (installed_path, sync_progress_task) = reload_guard .handle(async { - let download_path = ctx - .datadir + let download_path = Path::new(DATA_DIR) .join(PKG_ARCHIVE_DIR) .join("downloading") .join(&id) @@ -251,8 +252,7 @@ impl ServiceMap { file.sync_all().await?; download_progress.complete(); - let installed_path = ctx - .datadir + let installed_path = Path::new(DATA_DIR) .join(PKG_ARCHIVE_DIR) .join("installed") .join(&id) diff --git a/core/startos/src/service/transition/backup.rs b/core/startos/src/service/transition/backup.rs index 0d4116078..6205cdd61 100644 --- a/core/startos/src/service/transition/backup.rs +++ b/core/startos/src/service/transition/backup.rs @@ -15,6 +15,7 @@ use crate::service::ServiceActor; use crate::util::actor::background::BackgroundJobQueue; use crate::util::actor::{ConflictBuilder, Handler}; use crate::util::future::RemoteCancellable; +use crate::util::serde::NoOutput; pub(in crate::service) struct Backup { pub path: PathBuf, @@ -48,7 +49,7 @@ impl Handler for ServiceActor { .mount_backup(path, ReadWrite) .await?; seed.persistent_container - .execute(id, ProcedureName::CreateBackup, Value::Null, None) + .execute::(id, ProcedureName::CreateBackup, Value::Null, None) .await?; backup_guard.unmount(true).await?; diff --git a/core/startos/src/service/transition/restore.rs b/core/startos/src/service/transition/restore.rs index 1c4020ea4..7061b0c1e 100644 --- a/core/startos/src/service/transition/restore.rs +++ b/core/startos/src/service/transition/restore.rs @@ -11,6 +11,7 @@ use crate::service::ServiceActor; use crate::util::actor::background::BackgroundJobQueue; use crate::util::actor::{ConflictBuilder, Handler}; use crate::util::future::RemoteCancellable; +use crate::util::serde::NoOutput; pub(in crate::service) struct Restore { pub path: PathBuf, @@ -38,7 +39,7 @@ impl Handler for ServiceActor { .mount_backup(path, ReadOnly) .await?; seed.persistent_container - .execute(id, ProcedureName::RestoreBackup, Value::Null, None) + .execute::(id, ProcedureName::RestoreBackup, Value::Null, None) .await?; backup_guard.unmount(true).await?; @@ -48,7 +49,7 @@ impl Handler for ServiceActor { Ok::<_, Error>(()) } .map(|x| { - if let Err(err) = dbg!(x) { + if let Err(err) = x { tracing::debug!("{:?}", err); tracing::warn!("{}", err); } diff --git a/core/startos/src/setup.rs b/core/startos/src/setup.rs index 1319ffae4..e9109cabe 100644 --- a/core/startos/src/setup.rs +++ b/core/startos/src/setup.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use std::time::Duration; use color_eyre::eyre::eyre; +use const_format::formatcp; use josekit::jwk::Jwk; use patch_db::json_ptr::ROOT; use rpc_toolkit::yajrc::RpcError; @@ -38,7 +39,7 @@ use crate::rpc_continuations::Guid; use crate::util::crypto::EncryptedWire; use crate::util::io::{create_file, dir_copy, dir_size, Counter}; use crate::util::Invoke; -use crate::{Error, ErrorKind, ResultExt}; +use crate::{Error, ErrorKind, ResultExt, DATA_DIR, MAIN_DATA, PACKAGE_DATA}; pub fn setup() -> ParentHandler { ParentHandler::new() @@ -80,7 +81,7 @@ async fn setup_init( password: Option, init_phases: InitPhases, ) -> Result<(AccountInfo, PreInitNetController), Error> { - let InitResult { net_ctrl } = init(&ctx.config, init_phases).await?; + let InitResult { net_ctrl } = init(&ctx.webserver, &ctx.config, init_phases).await?; let account = net_ctrl .db @@ -140,7 +141,7 @@ pub async fn attach( disk_phase.start(); let requires_reboot = crate::disk::main::import( &*disk_guid, - &setup_ctx.datadir, + DATA_DIR, if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() { RepairStrategy::Aggressive } else { @@ -155,7 +156,7 @@ pub async fn attach( .with_ctx(|_| (ErrorKind::Filesystem, REPAIR_DISK_PATH))?; } if requires_reboot.0 { - crate::disk::main::export(&*disk_guid, &setup_ctx.datadir).await?; + crate::disk::main::export(&*disk_guid, DATA_DIR).await?; return Err(Error::new( eyre!( "Errors were corrected with your disk, but the server must be restarted in order to proceed" @@ -167,7 +168,7 @@ pub async fn attach( let (account, net_ctrl) = setup_init(&setup_ctx, password, init_phases).await?; - let rpc_ctx = RpcContext::init(&setup_ctx.config, disk_guid, Some(net_ctrl), rpc_ctx_phases).await?; + let rpc_ctx = RpcContext::init(&setup_ctx.webserver, &setup_ctx.config, disk_guid, Some(net_ctrl), rpc_ctx_phases).await?; Ok(((&account).try_into()?, rpc_ctx)) })?; @@ -391,18 +392,13 @@ pub async fn execute_inner( crate::disk::main::create( &[start_os_logicalname], &pvscan().await?, - &ctx.datadir, + DATA_DIR, encryption_password, ) .await?, ); - let _ = crate::disk::main::import( - &*guid, - &ctx.datadir, - RepairStrategy::Preen, - encryption_password, - ) - .await?; + let _ = crate::disk::main::import(&*guid, DATA_DIR, RepairStrategy::Preen, encryption_password) + .await?; disk_phase.complete(); let progress = SetupExecuteProgress { @@ -456,9 +452,16 @@ async fn fresh_setup( db.put(&ROOT, &Database::init(&account)?).await?; drop(db); - let InitResult { net_ctrl } = init(&ctx.config, init_phases).await?; + let InitResult { net_ctrl } = init(&ctx.webserver, &ctx.config, init_phases).await?; - let rpc_ctx = RpcContext::init(&ctx.config, guid, Some(net_ctrl), rpc_ctx_phases).await?; + let rpc_ctx = RpcContext::init( + &ctx.webserver, + &ctx.config, + guid, + Some(net_ctrl), + rpc_ctx_phases, + ) + .await?; Ok(((&account).try_into()?, rpc_ctx)) } @@ -513,10 +516,10 @@ async fn migrate( ) .await?; - let main_transfer_args = ("/media/startos/migrate/main/", "/embassy-data/main/"); + let main_transfer_args = ("/media/startos/migrate/main/", formatcp!("{MAIN_DATA}/")); let package_data_transfer_args = ( "/media/startos/migrate/package-data/", - "/embassy-data/package-data/", + formatcp!("{PACKAGE_DATA}/"), ); let tmpdir = Path::new(package_data_transfer_args.0).join("tmp"); @@ -571,7 +574,14 @@ async fn migrate( let (account, net_ctrl) = setup_init(&ctx, Some(start_os_password), init_phases).await?; - let rpc_ctx = RpcContext::init(&ctx.config, guid, Some(net_ctrl), rpc_ctx_phases).await?; + let rpc_ctx = RpcContext::init( + &ctx.webserver, + &ctx.config, + guid, + Some(net_ctrl), + rpc_ctx_phases, + ) + .await?; Ok(((&account).try_into()?, rpc_ctx)) } diff --git a/core/startos/src/shutdown.rs b/core/startos/src/shutdown.rs index f6a984897..4e45f74c0 100644 --- a/core/startos/src/shutdown.rs +++ b/core/startos/src/shutdown.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::Arc; use crate::context::RpcContext; @@ -7,7 +7,7 @@ use crate::init::{STANDBY_MODE_PATH, SYSTEM_REBUILD_PATH}; use crate::prelude::*; use crate::sound::SHUTDOWN; use crate::util::Invoke; -use crate::PLATFORM; +use crate::{DATA_DIR, PLATFORM}; #[derive(Debug, Clone)] pub struct Shutdown { @@ -87,7 +87,7 @@ pub async fn shutdown(ctx: RpcContext) -> Result<(), Error> { .await?; ctx.shutdown .send(Some(Shutdown { - export_args: Some((ctx.disk_guid.clone(), ctx.datadir.clone())), + export_args: Some((ctx.disk_guid.clone(), Path::new(DATA_DIR).to_owned())), restart: false, })) .map_err(|_| ()) @@ -107,7 +107,7 @@ pub async fn restart(ctx: RpcContext) -> Result<(), Error> { .await?; ctx.shutdown .send(Some(Shutdown { - export_args: Some((ctx.disk_guid.clone(), ctx.datadir.clone())), + export_args: Some((ctx.disk_guid.clone(), Path::new(DATA_DIR).to_owned())), restart: true, })) .map_err(|_| ()) diff --git a/core/startos/src/status/mod.rs b/core/startos/src/status/mod.rs index 398797a5a..cf1ca0658 100644 --- a/core/startos/src/status/mod.rs +++ b/core/startos/src/status/mod.rs @@ -80,7 +80,7 @@ impl MainStatus { } } - pub fn backing_up(self) -> Self { + pub fn backing_up(&self) -> Self { MainStatus::BackingUp { on_complete: if self.running() { StartStop::Start diff --git a/core/startos/src/system.rs b/core/startos/src/system.rs index d05af09b5..e44431894 100644 --- a/core/startos/src/system.rs +++ b/core/startos/src/system.rs @@ -30,6 +30,7 @@ use crate::util::cpupower::{get_available_governors, set_governor, Governor}; use crate::util::io::open_file; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; use crate::util::Invoke; +use crate::{MAIN_DATA, PACKAGE_DATA}; pub fn experimental() -> ParentHandler { ParentHandler::new() @@ -808,10 +809,10 @@ pub async fn get_mem_info() -> Result { #[instrument(skip_all)] async fn get_disk_info() -> Result { - let package_used_task = get_used("/embassy-data/package-data"); - let package_available_task = get_available("/embassy-data/package-data"); - let os_used_task = get_used("/embassy-data/main"); - let os_available_task = get_available("/embassy-data/main"); + let package_used_task = get_used(PACKAGE_DATA); + let package_available_task = get_available(PACKAGE_DATA); + let os_used_task = get_used(MAIN_DATA); + let os_available_task = get_available(MAIN_DATA); let (package_used, package_available, os_used, os_available) = futures::try_join!( package_used_task, diff --git a/core/startos/src/update/mod.rs b/core/startos/src/update/mod.rs index 51d8d77ae..d88838d4a 100644 --- a/core/startos/src/update/mod.rs +++ b/core/startos/src/update/mod.rs @@ -20,7 +20,7 @@ use ts_rs::TS; use crate::context::{CliContext, RpcContext}; use crate::disk::mount::filesystem::bind::Bind; use crate::disk::mount::filesystem::block_dev::BlockDev; -use crate::disk::mount::filesystem::efivarfs::{self, EfiVarFs}; +use crate::disk::mount::filesystem::efivarfs::{ EfiVarFs}; use crate::disk::mount::filesystem::overlayfs::OverlayGuard; use crate::disk::mount::filesystem::MountType; use crate::disk::mount::guard::{GenericMountGuard, MountGuard, TmpMountGuard}; diff --git a/core/startos/src/util/actor/background.rs b/core/startos/src/util/actor/background.rs index f37e10c14..7666cbf04 100644 --- a/core/startos/src/util/actor/background.rs +++ b/core/startos/src/util/actor/background.rs @@ -15,8 +15,13 @@ impl BackgroundJobQueue { }, ) } - pub fn add_job(&self, fut: impl Future + Send + 'static) { - let _ = self.0.send(fut.boxed()); + pub fn add_job(&self, fut: impl Future + Send + 'static) { + let _ = self.0.send( + async { + fut.await; + } + .boxed(), + ); } } diff --git a/core/startos/src/util/future.rs b/core/startos/src/util/future.rs index f40e847bf..c690f9754 100644 --- a/core/startos/src/util/future.rs +++ b/core/startos/src/util/future.rs @@ -1,11 +1,13 @@ use std::pin::Pin; use std::task::{Context, Poll}; -use futures::future::abortable; -use futures::stream::{AbortHandle, Abortable}; -use futures::Future; +use futures::future::{abortable, pending, BoxFuture, FusedFuture}; +use futures::stream::{AbortHandle, Abortable, BoxStream}; +use futures::{Future, FutureExt, Stream, StreamExt}; use tokio::sync::watch; +use crate::prelude::*; + #[pin_project::pin_project(PinnedDrop)] pub struct DropSignaling { #[pin] @@ -102,6 +104,60 @@ impl CancellationHandle { } } +#[derive(Default)] +pub struct Until<'a> { + streams: Vec>>, + async_fns: Vec BoxFuture<'a, Result<(), Error>> + Send + 'a>>, +} +impl<'a> Until<'a> { + pub fn new() -> Self { + Self::default() + } + + pub fn with_stream( + mut self, + stream: impl Stream> + Send + 'a, + ) -> Self { + self.streams.push(stream.boxed()); + self + } + + pub fn with_async_fn(mut self, mut f: F) -> Self + where + F: FnMut() -> Fut + Send + 'a, + Fut: Future> + FusedFuture + Send + 'a, + { + self.async_fns.push(Box::new(move || f().boxed())); + self + } + + pub async fn run> + Send>( + &mut self, + fut: Fut, + ) -> Result<(), Error> { + let (res, _, _) = futures::future::select_all( + self.streams + .iter_mut() + .map(|s| { + async { + s.next().await.transpose()?.ok_or_else(|| { + Error::new(eyre!("stream is empty"), ErrorKind::Cancelled) + }) + } + .boxed() + }) + .chain(self.async_fns.iter_mut().map(|f| f())) + .chain([async { + fut.await?; + pending().await + } + .boxed()]), + ) + .await; + res + } +} + #[tokio::test] async fn test_cancellable() { use std::sync::Arc; diff --git a/core/startos/src/util/io.rs b/core/startos/src/util/io.rs index 0e7aada54..f0bae7a0a 100644 --- a/core/startos/src/util/io.rs +++ b/core/startos/src/util/io.rs @@ -15,7 +15,7 @@ use futures::future::{BoxFuture, Fuse}; use futures::{AsyncSeek, FutureExt, Stream, TryStreamExt}; use helpers::NonDetachingJoinHandle; use nix::unistd::{Gid, Uid}; -use tokio::fs::File; +use tokio::fs::{File, OpenOptions}; use tokio::io::{ duplex, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, DuplexStream, ReadBuf, WriteHalf, }; @@ -460,18 +460,30 @@ impl BackTrackingIO { } } } - pub fn rewind(&mut self) -> Vec { + pub fn rewind<'a>(&'a mut self) -> (Vec, &'a [u8]) { match std::mem::take(&mut self.buffer) { BTBuffer::Buffering { read, write } => { self.buffer = BTBuffer::Rewound { read: Cursor::new(read), }; - write + ( + write, + match &self.buffer { + BTBuffer::Rewound { read } => read.get_ref(), + _ => unreachable!(), + }, + ) } - BTBuffer::NotBuffering => Vec::new(), + BTBuffer::NotBuffering => (Vec::new(), &[]), BTBuffer::Rewound { read } => { self.buffer = BTBuffer::Rewound { read }; - Vec::new() + ( + Vec::new(), + match &self.buffer { + BTBuffer::Rewound { read } => read.get_ref(), + _ => unreachable!(), + }, + ) } } } @@ -529,7 +541,6 @@ impl std::io::Read for BackTrackingIO { } BTBuffer::NotBuffering => self.io.read(buf), BTBuffer::Rewound { read } => { - let mut ready = false; if (read.position() as usize) < read.get_ref().len() { let n = std::io::Read::read(read, buf)?; if n != 0 { @@ -923,6 +934,21 @@ pub async fn create_file(path: impl AsRef) -> Result { .with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("create {path:?}"))) } +pub async fn append_file(path: impl AsRef) -> Result { + let path = path.as_ref(); + if let Some(parent) = path.parent() { + tokio::fs::create_dir_all(parent) + .await + .with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("mkdir -p {parent:?}")))?; + } + OpenOptions::new() + .create(true) + .append(true) + .open(path) + .await + .with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("create {path:?}"))) +} + pub async fn delete_file(path: impl AsRef) -> Result<(), Error> { let path = path.as_ref(); tokio::fs::remove_file(path) diff --git a/core/startos/src/util/logger.rs b/core/startos/src/util/logger.rs index c464b328d..816721d5b 100644 --- a/core/startos/src/util/logger.rs +++ b/core/startos/src/util/logger.rs @@ -1,13 +1,62 @@ -use std::io; +use std::fs::File; +use std::io::{self, Write}; +use std::sync::{Arc, Mutex, MutexGuard}; +use lazy_static::lazy_static; use tracing::Subscriber; +use tracing_subscriber::fmt::MakeWriter; use tracing_subscriber::util::SubscriberInitExt; -#[derive(Clone)] -pub struct EmbassyLogger {} +lazy_static! { + pub static ref LOGGER: StartOSLogger = StartOSLogger::init(); +} -impl EmbassyLogger { - fn base_subscriber() -> impl Subscriber { +#[derive(Clone)] +pub struct StartOSLogger { + logfile: LogFile, +} + +#[derive(Clone, Default)] +struct LogFile(Arc>>); +impl<'a> MakeWriter<'a> for LogFile { + type Writer = Box; + fn make_writer(&'a self) -> Self::Writer { + let f = self.0.lock().unwrap(); + if f.is_some() { + struct TeeWriter<'a>(MutexGuard<'a, Option>); + impl<'a> Write for TeeWriter<'a> { + fn write(&mut self, buf: &[u8]) -> io::Result { + let n = if let Some(f) = &mut *self.0 { + f.write(buf)? + } else { + buf.len() + }; + io::stderr().write_all(&buf[..n])?; + Ok(n) + } + fn flush(&mut self) -> io::Result<()> { + if let Some(f) = &mut *self.0 { + f.flush()?; + } + Ok(()) + } + } + Box::new(TeeWriter(f)) + } else { + drop(f); + Box::new(io::stderr()) + } + } +} + +impl StartOSLogger { + pub fn enable(&self) {} + + pub fn set_logfile(&self, logfile: Option) { + *self.logfile.0.lock().unwrap() = logfile; + } + + fn base_subscriber(logfile: LogFile) -> impl Subscriber { use tracing_error::ErrorLayer; use tracing_subscriber::prelude::*; use tracing_subscriber::{fmt, EnvFilter}; @@ -24,7 +73,7 @@ impl EmbassyLogger { .add_directive("tokio=trace".parse().unwrap()) .add_directive("runtime=trace".parse().unwrap()); let fmt_layer = fmt::layer() - .with_writer(io::stderr) + .with_writer(logfile) .with_line_number(true) .with_file(true) .with_target(true); @@ -39,11 +88,12 @@ impl EmbassyLogger { sub } - pub fn init() -> Self { - Self::base_subscriber().init(); + fn init() -> Self { + let logfile = LogFile::default(); + Self::base_subscriber(logfile.clone()).init(); color_eyre::install().unwrap_or_else(|_| tracing::warn!("tracing too many times")); - EmbassyLogger {} + StartOSLogger { logfile } } } diff --git a/core/startos/src/util/rpc.rs b/core/startos/src/util/rpc.rs index b2dea340e..f7c91eb82 100644 --- a/core/startos/src/util/rpc.rs +++ b/core/startos/src/util/rpc.rs @@ -3,7 +3,6 @@ use std::path::Path; use clap::Parser; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; -use url::Url; use crate::context::CliContext; use crate::prelude::*; diff --git a/core/startos/src/util/rpc_client.rs b/core/startos/src/util/rpc_client.rs index fc93e4c64..82ce11e20 100644 --- a/core/startos/src/util/rpc_client.rs +++ b/core/startos/src/util/rpc_client.rs @@ -47,7 +47,7 @@ impl RpcClient { let mut lines = BufReader::new(reader).lines(); while let Some(line) = lines.next_line().await.transpose() { match line.map_err(Error::from).and_then(|l| { - serde_json::from_str::(dbg!(&l)) + serde_json::from_str::(crate::dbg!(&l)) .with_kind(ErrorKind::Deserialization) }) { Ok(l) => { @@ -114,7 +114,7 @@ impl RpcClient { let (send, recv) = oneshot::channel(); w.lock().await.insert(id.clone(), send); self.writer - .write_all((dbg!(serde_json::to_string(&request))? + "\n").as_bytes()) + .write_all((crate::dbg!(serde_json::to_string(&request))? + "\n").as_bytes()) .await .map_err(|e| { let mut err = rpc_toolkit::yajrc::INTERNAL_ERROR.clone(); @@ -154,7 +154,7 @@ impl RpcClient { params, }; self.writer - .write_all((dbg!(serde_json::to_string(&request))? + "\n").as_bytes()) + .write_all((crate::dbg!(serde_json::to_string(&request))? + "\n").as_bytes()) .await .map_err(|e| { let mut err = rpc_toolkit::yajrc::INTERNAL_ERROR.clone(); diff --git a/core/startos/src/util/sync.rs b/core/startos/src/util/sync.rs index 1edd21ce1..2630858a9 100644 --- a/core/startos/src/util/sync.rs +++ b/core/startos/src/util/sync.rs @@ -1,3 +1,4 @@ +#[derive(Debug, Default)] pub struct SyncMutex(std::sync::Mutex); impl SyncMutex { pub fn new(t: T) -> Self { diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index 94b61176b..e8d5f2249 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -7,12 +7,10 @@ use futures::future::BoxFuture; use futures::{Future, FutureExt}; use imbl::Vector; use imbl_value::{to_value, InternedString}; -use patch_db::json_ptr::{JsonPointer, ROOT}; +use patch_db::json_ptr::{ ROOT}; use crate::context::RpcContext; -use crate::db::model::Database; use crate::prelude::*; -use crate::progress::PhaseProgressTrackerHandle; use crate::Error; mod v0_3_5; @@ -29,7 +27,9 @@ mod v0_3_6_alpha_7; mod v0_3_6_alpha_8; mod v0_3_6_alpha_9; -pub type Current = v0_3_6_alpha_9::Version; // VERSION_BUMP +mod v0_3_6_alpha_10; + +pub type Current = v0_3_6_alpha_10::Version; // VERSION_BUMP impl Current { #[instrument(skip(self, db))] @@ -108,6 +108,7 @@ enum Version { V0_3_6_alpha_7(Wrapper), V0_3_6_alpha_8(Wrapper), V0_3_6_alpha_9(Wrapper), + V0_3_6_alpha_10(Wrapper), Other(exver::Version), } @@ -141,6 +142,7 @@ impl Version { Self::V0_3_6_alpha_7(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_8(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_9(v) => DynVersion(Box::new(v.0)), + Self::V0_3_6_alpha_10(v) => DynVersion(Box::new(v.0)), Self::Other(v) => { return Err(Error::new( eyre!("unknown version {v}"), @@ -166,6 +168,7 @@ impl Version { Version::V0_3_6_alpha_7(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_8(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_9(Wrapper(x)) => x.semver(), + Version::V0_3_6_alpha_10(Wrapper(x)) => x.semver(), Version::Other(x) => x.clone(), } } diff --git a/core/startos/src/version/v0_3_6_alpha_0.rs b/core/startos/src/version/v0_3_6_alpha_0.rs index 7a6045a3a..7c594a9f9 100644 --- a/core/startos/src/version/v0_3_6_alpha_0.rs +++ b/core/startos/src/version/v0_3_6_alpha_0.rs @@ -1,19 +1,16 @@ use std::collections::BTreeMap; -use std::future::Future; use std::path::Path; use chrono::{DateTime, Utc}; +use const_format::formatcp; use ed25519_dalek::SigningKey; use exver::{PreReleaseSegment, VersionRange}; use imbl_value::{json, InternedString}; -use itertools::Itertools; use models::PackageId; -use openssl::pkey::{PKey, Private}; +use openssl::pkey::PKey; use openssl::x509::X509; -use patch_db::ModelExt; use sqlx::postgres::PgConnectOptions; use sqlx::{PgPool, Row}; -use ssh_key::Fingerprint; use tokio::process::Command; use torut::onion::TorSecretKeyV3; @@ -23,15 +20,11 @@ use crate::account::AccountInfo; use crate::auth::Sessions; use crate::backup::target::cifs::CifsTargets; use crate::context::RpcContext; -use crate::db::model::Database; use crate::disk::mount::filesystem::cifs::Cifs; use crate::disk::mount::util::unmount; use crate::hostname::Hostname; use crate::net::forward::AvailablePorts; use crate::net::keys::KeyStore; -use crate::net::ssl::CertStore; -use crate::net::tor; -use crate::net::tor::OnionStore; use crate::notifications::{Notification, Notifications}; use crate::prelude::*; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; @@ -39,6 +32,7 @@ use crate::ssh::{SshKeys, SshPubKey}; use crate::util::crypto::ed25519_expand_key; use crate::util::serde::{Pem, PemEncoding}; use crate::util::Invoke; +use crate::{DATA_DIR, PACKAGE_DATA}; lazy_static::lazy_static! { static ref V0_3_6_alpha_0: exver::Version = exver::Version::new( @@ -191,7 +185,6 @@ async fn init_postgres(datadir: impl AsRef) -> Result { .run(&secret_store) .await .with_kind(crate::ErrorKind::Database)?; - dbg!("Init Postgres Done"); Ok(secret_store) } @@ -208,7 +201,7 @@ impl VersionT for Version { &V0_3_0_COMPAT } async fn pre_up(self) -> Result { - let pg = init_postgres("/embassy-data").await?; + let pg = init_postgres(DATA_DIR).await?; let account = previous_account_info(&pg).await?; let ssh_keys = previous_ssh_keys(&pg).await?; @@ -315,7 +308,6 @@ impl VersionT for Version { "private": private, }); - dbg!("Should be done with the up"); *db = next; Ok(()) } @@ -329,7 +321,7 @@ impl VersionT for Version { #[instrument(skip(self, ctx))] /// MUST be idempotent, and is run after *all* db migrations async fn post_up(self, ctx: &RpcContext) -> Result<(), Error> { - let path = Path::new("/embassy-data/package-data/archive/"); + let path = Path::new(formatcp!("{PACKAGE_DATA}/archive/")); if !path.is_dir() { return Err(Error::new( eyre!( diff --git a/core/startos/src/version/v0_3_6_alpha_10.rs b/core/startos/src/version/v0_3_6_alpha_10.rs new file mode 100644 index 000000000..d81fc91ca --- /dev/null +++ b/core/startos/src/version/v0_3_6_alpha_10.rs @@ -0,0 +1,94 @@ +use std::collections::{BTreeMap, BTreeSet}; + +use exver::{PreReleaseSegment, VersionRange}; +use imbl_value::InternedString; +use serde::{Deserialize, Serialize}; +use torut::onion::OnionAddressV3; + +use super::v0_3_5::V0_3_0_COMPAT; +use super::{v0_3_6_alpha_9, VersionT}; +use crate::net::host::address::DomainConfig; +use crate::prelude::*; + +lazy_static::lazy_static! { + static ref V0_3_6_alpha_10: exver::Version = exver::Version::new( + [0, 3, 6], + [PreReleaseSegment::String("alpha".into()), 10.into()] + ); +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] +#[serde(rename_all = "camelCase")] +#[serde(tag = "kind")] +enum HostAddress { + Onion { address: OnionAddressV3 }, + Domain { address: InternedString }, +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct Version; + +impl VersionT for Version { + type Previous = v0_3_6_alpha_9::Version; + type PreUpRes = (); + + async fn pre_up(self) -> Result { + Ok(()) + } + fn semver(self) -> exver::Version { + V0_3_6_alpha_10.clone() + } + fn compat(self) -> &'static VersionRange { + &V0_3_0_COMPAT + } + fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { + for (_, package) in db["public"]["packageData"] + .as_object_mut() + .ok_or_else(|| { + Error::new( + eyre!("expected public.packageData to be an object"), + ErrorKind::Database, + ) + })? + .iter_mut() + { + for (_, host) in package["hosts"] + .as_object_mut() + .ok_or_else(|| { + Error::new( + eyre!("expected public.packageData[id].hosts to be an object"), + ErrorKind::Database, + ) + })? + .iter_mut() + { + let mut onions = BTreeSet::new(); + let mut domains = BTreeMap::new(); + let addresses = from_value::>(host["addresses"].clone())?; + for address in addresses { + match address { + HostAddress::Onion { address } => { + onions.insert(address); + } + HostAddress::Domain { address } => { + domains.insert( + address, + DomainConfig { + public: true, + acme: None, + }, + ); + } + } + } + host["onions"] = to_value(&onions)?; + host["domains"] = to_value(&domains)?; + } + } + + Ok(()) + } + fn down(self, _db: &mut Value) -> Result<(), Error> { + Ok(()) + } +} diff --git a/core/startos/src/version/v0_3_6_alpha_6.rs b/core/startos/src/version/v0_3_6_alpha_6.rs index d91caa82b..7d62773ea 100644 --- a/core/startos/src/version/v0_3_6_alpha_6.rs +++ b/core/startos/src/version/v0_3_6_alpha_6.rs @@ -27,7 +27,7 @@ impl VersionT for Version { async fn pre_up(self) -> Result { Ok(()) } - fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { + fn up(self, _db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { Ok(()) } async fn post_up<'a>(self, ctx: &'a crate::context::RpcContext) -> Result<(), Error> { diff --git a/core/startos/src/version/v0_3_6_alpha_7.rs b/core/startos/src/version/v0_3_6_alpha_7.rs index bbf9468ff..baf7aaa35 100644 --- a/core/startos/src/version/v0_3_6_alpha_7.rs +++ b/core/startos/src/version/v0_3_6_alpha_7.rs @@ -1,5 +1,5 @@ use exver::{PreReleaseSegment, VersionRange}; -use imbl_value::{json, InOMap}; +use imbl_value::json; use tokio::process::Command; use super::v0_3_5::V0_3_0_COMPAT; diff --git a/core/startos/src/version/v0_3_6_alpha_8.rs b/core/startos/src/version/v0_3_6_alpha_8.rs index fcef96a69..99920c767 100644 --- a/core/startos/src/version/v0_3_6_alpha_8.rs +++ b/core/startos/src/version/v0_3_6_alpha_8.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use exver::{PreReleaseSegment, VersionRange}; use tokio::fs::File; @@ -12,6 +14,7 @@ use crate::s9pk::v2::SIG_CONTEXT; use crate::s9pk::S9pk; use crate::service::LoadDisposition; use crate::util::io::create_file; +use crate::DATA_DIR; lazy_static::lazy_static! { static ref V0_3_6_alpha_8: exver::Version = exver::Version::new( @@ -40,7 +43,7 @@ impl VersionT for Version { Ok(()) } async fn post_up(self, ctx: &crate::context::RpcContext) -> Result<(), Error> { - let s9pk_dir = ctx.datadir.join(PKG_ARCHIVE_DIR).join("installed"); + let s9pk_dir = Path::new(DATA_DIR).join(PKG_ARCHIVE_DIR).join("installed"); if tokio::fs::metadata(&s9pk_dir).await.is_ok() { let mut read_dir = tokio::fs::read_dir(&s9pk_dir).await?; diff --git a/core/startos/src/volume.rs b/core/startos/src/volume.rs index c7165b202..113802286 100644 --- a/core/startos/src/volume.rs +++ b/core/startos/src/volume.rs @@ -1,10 +1,9 @@ use std::path::{Path, PathBuf}; pub use helpers::script_dir; +use models::PackageId; pub use models::VolumeId; -use models::{HostId, PackageId}; -use crate::net::PACKAGE_CERT_PATH; use crate::prelude::*; use crate::util::VersionString; @@ -36,7 +35,3 @@ pub fn asset_dir>( pub fn backup_dir(pkg_id: &PackageId) -> PathBuf { Path::new(BACKUP_DIR).join(pkg_id).join("data") } - -pub fn cert_dir(pkg_id: &PackageId, host_id: &HostId) -> PathBuf { - Path::new(PACKAGE_CERT_PATH).join(pkg_id).join(host_id) -} diff --git a/debian/postinst b/debian/postinst index bf9a8938e..14164dbf1 100755 --- a/debian/postinst +++ b/debian/postinst @@ -86,6 +86,8 @@ sed -i '/^\s*#\?\s*issue_discards\s*=\s*/c\issue_discards = 1' /etc/lvm/lvm.conf sed -i '/\(^\|#\)\s*unqualified-search-registries\s*=\s*/c\unqualified-search-registries = ["docker.io"]' /etc/containers/registries.conf sed -i 's/\(#\|\^\)\s*\([^=]\+\)=\(suspend\|hibernate\)\s*$/\2=ignore/g' /etc/systemd/logind.conf sed -i '/\(^\|#\)MulticastDNS=/c\MulticastDNS=no' /etc/systemd/resolved.conf +sed -i 's/\[Service\]/[Service]\nEnvironment=SYSTEMD_LOG_LEVEL=debug/' /lib/systemd/system/systemd-timesyncd.service +sed -i '/\(^\|#\)RootDistanceMaxSec=/c\RootDistanceMaxSec=10' /etc/systemd/timesyncd.conf mkdir -p /etc/nginx/ssl @@ -103,7 +105,7 @@ rm -rf /var/lib/tor/* ln -sf /usr/lib/startos/scripts/tor-check.sh /usr/bin/tor-check ln -sf /usr/lib/startos/scripts/gather_debug_info.sh /usr/bin/gather-debug -echo "fs.inotify.max_user_watches=1048576" > /etc/sysctl.d/97-embassy.conf +echo "fs.inotify.max_user_watches=1048576" > /etc/sysctl.d/97-startos.conf # Old pi was set with this locale, because of pg we are now stuck with including that locale locale-gen en_GB en_GB.UTF-8 @@ -112,16 +114,14 @@ update-locale LANGUAGE rm -f "/etc/locale.gen" dpkg-reconfigure --frontend noninteractive locales -if ! getent group | grep '^embassy:'; then - groupadd embassy +if ! getent group | grep '^startos:'; then + groupadd startos fi -ln -sf /usr/lib/startos/scripts/dhclient-exit-hook /etc/dhcp/dhclient-exit-hooks.d/embassy - rm -f /etc/motd -ln -sf /usr/lib/startos/motd /etc/update-motd.d/00-embassy +ln -sf /usr/lib/startos/motd /etc/update-motd.d/00-startos chmod -x /etc/update-motd.d/* -chmod +x /etc/update-motd.d/00-embassy +chmod +x /etc/update-motd.d/00-startos # LXC cat /etc/subuid | grep -v '^root:' > /etc/subuid.tmp || true diff --git a/image-recipe/build.sh b/image-recipe/build.sh index 4ce2d6dac..9e61999e6 100755 --- a/image-recipe/build.sh +++ b/image-recipe/build.sh @@ -166,7 +166,7 @@ echo "deb [arch=${IB_TARGET_ARCH} signed-by=/etc/apt/trusted.gpg.d/docker.key.gp # Dependencies ## Base dependencies -dpkg-deb --fsys-tarfile $base_dir/deb/${IMAGE_BASENAME}.deb | tar --to-stdout -xvf - ./usr/lib/startos/depends > config/package-lists/embassy-depends.list.chroot +dpkg-deb --fsys-tarfile $base_dir/deb/${IMAGE_BASENAME}.deb | tar --to-stdout -xvf - ./usr/lib/startos/depends > config/package-lists/startos-depends.list.chroot ## Firmware if [ "$NON_FREE" = 1 ]; then @@ -210,7 +210,7 @@ if [ "${IB_TARGET_PLATFORM}" = "raspberrypi" ]; then mkinitramfs -c gzip -o /boot/initramfs_2712 6.6.62-v8-16k+ fi -useradd --shell /bin/bash -G embassy -m start9 +useradd --shell /bin/bash -G startos -m start9 echo start9:embassy | chpasswd usermod -aG sudo start9 diff --git a/patch-db b/patch-db index 99076d349..2600a784a 160000 --- a/patch-db +++ b/patch-db @@ -1 +1 @@ -Subproject commit 99076d349c6768000483ea8d47216d273586552e +Subproject commit 2600a784a9899a6f8e0c9abe0bf4c4ce48cb85a9 diff --git a/sdk/base/lib/Effects.ts b/sdk/base/lib/Effects.ts index e4424fafb..dcb03af4e 100644 --- a/sdk/base/lib/Effects.ts +++ b/sdk/base/lib/Effects.ts @@ -8,7 +8,7 @@ import { SetHealth, BindParams, HostId, - LanInfo, + NetInfo, Host, ExportServiceInterfaceParams, ServiceInterface, @@ -117,7 +117,7 @@ export type Effects = { packageId?: PackageId hostId: HostId internalPort: number - }): Promise + }): Promise /** Removes all network bindings, called in the setupInputSpec */ clearBindings(options: { except: { id: HostId; internalPort: number }[] @@ -129,12 +129,6 @@ export type Effects = { hostId: HostId callback?: () => void }): Promise - /** Returns the primary url that a user has selected for a host, if it exists */ - getPrimaryUrl(options: { - packageId?: PackageId - hostId: HostId - callback?: () => void - }): Promise /** Returns the IP address of the container */ getContainerIp(): Promise // interface diff --git a/sdk/base/lib/actions/input/builder/inputSpec.ts b/sdk/base/lib/actions/input/builder/inputSpec.ts index 31e06df4f..5d4d5c6bb 100644 --- a/sdk/base/lib/actions/input/builder/inputSpec.ts +++ b/sdk/base/lib/actions/input/builder/inputSpec.ts @@ -94,8 +94,8 @@ export class InputSpec, Store = never> { }, public validator: Parser, ) {} - _TYPE: Type = null as any as Type - _PARTIAL: DeepPartial = null as any as DeepPartial + public _TYPE: Type = null as any as Type + public _PARTIAL: DeepPartial = null as any as DeepPartial async build(options: LazyBuildOptions) { const answer = {} as { [K in keyof Type]: ValueSpec diff --git a/sdk/base/lib/actions/input/builder/value.ts b/sdk/base/lib/actions/input/builder/value.ts index 676c4aac1..3ff3c2d24 100644 --- a/sdk/base/lib/actions/input/builder/value.ts +++ b/sdk/base/lib/actions/input/builder/value.ts @@ -49,6 +49,9 @@ export class Value { public build: LazyBuild, public validator: Parser, ) {} + public _TYPE: Type = null as any as Type + public _PARTIAL: DeepPartial = null as any as DeepPartial + static toggle(a: { name: string description?: string | null diff --git a/sdk/base/lib/dependencies/setupDependencies.ts b/sdk/base/lib/dependencies/setupDependencies.ts index 6b15ef0d1..4583ae749 100644 --- a/sdk/base/lib/dependencies/setupDependencies.ts +++ b/sdk/base/lib/dependencies/setupDependencies.ts @@ -31,7 +31,7 @@ export type CurrentDependenciesResult = { [K in RequiredDependenciesOf]: DependencyRequirement } & { [K in OptionalDependenciesOf]?: DependencyRequirement -} & Record +} export function setupDependencies( fn: (options: { @@ -48,14 +48,16 @@ export function setupDependencies( } const dependencyType = await fn(options) return await options.effects.setDependencies({ - dependencies: Object.entries(dependencyType).map( - ([id, { versionRange, ...x }, ,]) => - ({ - // id, - ...x, - versionRange: versionRange.toString(), - }) as T.DependencyRequirement, - ), + dependencies: Object.entries(dependencyType) + .map(([k, v]) => [k, v as DependencyRequirement] as const) + .map( + ([id, { versionRange, ...x }]) => + ({ + id, + ...x, + versionRange: versionRange.toString(), + }) as T.DependencyRequirement, + ), }) } return cell.updater diff --git a/sdk/base/lib/interfaces/Origin.ts b/sdk/base/lib/interfaces/Origin.ts index 5e12713e6..9985176e4 100644 --- a/sdk/base/lib/interfaces/Origin.ts +++ b/sdk/base/lib/interfaces/Origin.ts @@ -46,7 +46,6 @@ export class Origin { const { name, description, - hasPrimary, id, type, username, @@ -67,7 +66,6 @@ export class Origin { id, name, description, - hasPrimary, addressInfo, type, masked, diff --git a/sdk/base/lib/interfaces/ServiceInterfaceBuilder.ts b/sdk/base/lib/interfaces/ServiceInterfaceBuilder.ts index 4ef294b4f..036180ad3 100644 --- a/sdk/base/lib/interfaces/ServiceInterfaceBuilder.ts +++ b/sdk/base/lib/interfaces/ServiceInterfaceBuilder.ts @@ -20,7 +20,6 @@ export class ServiceInterfaceBuilder { name: string id: string description: string - hasPrimary: boolean type: ServiceInterfaceType username: string | null path: string diff --git a/sdk/base/lib/osBindings/HostAddress.ts b/sdk/base/lib/osBindings/AcmeProvider.ts similarity index 51% rename from sdk/base/lib/osBindings/HostAddress.ts rename to sdk/base/lib/osBindings/AcmeProvider.ts index 73b46d8e5..0ad3f0052 100644 --- a/sdk/base/lib/osBindings/HostAddress.ts +++ b/sdk/base/lib/osBindings/AcmeProvider.ts @@ -1,5 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type HostAddress = - | { kind: "onion"; address: string } - | { kind: "domain"; address: string } +export type AcmeProvider = string diff --git a/sdk/base/lib/osBindings/AcmeSettings.ts b/sdk/base/lib/osBindings/AcmeSettings.ts index bdf151ec7..44e70d9df 100644 --- a/sdk/base/lib/osBindings/AcmeSettings.ts +++ b/sdk/base/lib/osBindings/AcmeSettings.ts @@ -1,13 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type AcmeSettings = { - provider: string - /** - * email addresses for letsencrypt - */ - contact: Array - /** - * domains to get letsencrypt certs for - */ - domains: string[] -} +export type AcmeSettings = { contact: Array } diff --git a/sdk/base/lib/osBindings/BindInfo.ts b/sdk/base/lib/osBindings/BindInfo.ts index 85fc38e94..b03dbe6b2 100644 --- a/sdk/base/lib/osBindings/BindInfo.ts +++ b/sdk/base/lib/osBindings/BindInfo.ts @@ -1,5 +1,5 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { BindOptions } from "./BindOptions" -import type { LanInfo } from "./LanInfo" +import type { NetInfo } from "./NetInfo" -export type BindInfo = { enabled: boolean; options: BindOptions; lan: LanInfo } +export type BindInfo = { enabled: boolean; options: BindOptions; net: NetInfo } diff --git a/sdk/base/lib/osBindings/DomainConfig.ts b/sdk/base/lib/osBindings/DomainConfig.ts new file mode 100644 index 000000000..433bc65f5 --- /dev/null +++ b/sdk/base/lib/osBindings/DomainConfig.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AcmeProvider } from "./AcmeProvider" + +export type DomainConfig = { public: boolean; acme: AcmeProvider | null } diff --git a/sdk/base/lib/osBindings/ExportServiceInterfaceParams.ts b/sdk/base/lib/osBindings/ExportServiceInterfaceParams.ts index 28ac89916..675c3e06d 100644 --- a/sdk/base/lib/osBindings/ExportServiceInterfaceParams.ts +++ b/sdk/base/lib/osBindings/ExportServiceInterfaceParams.ts @@ -7,7 +7,6 @@ export type ExportServiceInterfaceParams = { id: ServiceInterfaceId name: string description: string - hasPrimary: boolean masked: boolean addressInfo: AddressInfo type: ServiceInterfaceType diff --git a/sdk/base/lib/osBindings/ForgetInterfaceParams.ts b/sdk/base/lib/osBindings/ForgetInterfaceParams.ts new file mode 100644 index 000000000..b3532602c --- /dev/null +++ b/sdk/base/lib/osBindings/ForgetInterfaceParams.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type ForgetInterfaceParams = { interface: string } diff --git a/sdk/base/lib/osBindings/GetPrimaryUrlParams.ts b/sdk/base/lib/osBindings/GetPrimaryUrlParams.ts deleted file mode 100644 index 06bf73976..000000000 --- a/sdk/base/lib/osBindings/GetPrimaryUrlParams.ts +++ /dev/null @@ -1,10 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { CallbackId } from "./CallbackId" -import type { HostId } from "./HostId" -import type { PackageId } from "./PackageId" - -export type GetPrimaryUrlParams = { - packageId?: PackageId - hostId: HostId - callback?: CallbackId -} diff --git a/sdk/base/lib/osBindings/GitHash.ts b/sdk/base/lib/osBindings/GitHash.ts new file mode 100644 index 000000000..43f6adde3 --- /dev/null +++ b/sdk/base/lib/osBindings/GitHash.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type GitHash = string diff --git a/sdk/base/lib/osBindings/Host.ts b/sdk/base/lib/osBindings/Host.ts index 7d8cf3a90..5436e9955 100644 --- a/sdk/base/lib/osBindings/Host.ts +++ b/sdk/base/lib/osBindings/Host.ts @@ -1,13 +1,14 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { BindInfo } from "./BindInfo" -import type { HostAddress } from "./HostAddress" +import type { DomainConfig } from "./DomainConfig" import type { HostKind } from "./HostKind" import type { HostnameInfo } from "./HostnameInfo" export type Host = { kind: HostKind bindings: { [key: number]: BindInfo } - addresses: Array + onions: string[] + domains: { [key: string]: DomainConfig } /** * COMPUTED: NetService::update */ diff --git a/sdk/base/lib/osBindings/IpHostname.ts b/sdk/base/lib/osBindings/IpHostname.ts index 4a6b5e87c..9b3ddd6d1 100644 --- a/sdk/base/lib/osBindings/IpHostname.ts +++ b/sdk/base/lib/osBindings/IpHostname.ts @@ -2,7 +2,13 @@ export type IpHostname = | { kind: "ipv4"; value: string; port: number | null; sslPort: number | null } - | { kind: "ipv6"; value: string; port: number | null; sslPort: number | null } + | { + kind: "ipv6" + value: string + scopeId: number + port: number | null + sslPort: number | null + } | { kind: "local" value: string diff --git a/sdk/base/lib/osBindings/IpInfo.ts b/sdk/base/lib/osBindings/IpInfo.ts index ae8c88d1b..260add9e6 100644 --- a/sdk/base/lib/osBindings/IpInfo.ts +++ b/sdk/base/lib/osBindings/IpInfo.ts @@ -1,8 +1,10 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { NetworkInterfaceType } from "./NetworkInterfaceType" export type IpInfo = { - ipv4Range: string | null - ipv4: string | null - ipv6Range: string | null - ipv6: string | null + scopeId: number + deviceType: NetworkInterfaceType | null + subnets: string[] + wanIp: string | null + ntpServers: string[] } diff --git a/sdk/base/lib/osBindings/Manifest.ts b/sdk/base/lib/osBindings/Manifest.ts index 8007b565b..2c9a2457e 100644 --- a/sdk/base/lib/osBindings/Manifest.ts +++ b/sdk/base/lib/osBindings/Manifest.ts @@ -2,6 +2,7 @@ import type { Alerts } from "./Alerts" import type { Dependencies } from "./Dependencies" import type { Description } from "./Description" +import type { GitHash } from "./GitHash" import type { HardwareRequirements } from "./HardwareRequirements" import type { ImageConfig } from "./ImageConfig" import type { ImageId } from "./ImageId" @@ -30,6 +31,6 @@ export type Manifest = { alerts: Alerts dependencies: Dependencies hardwareRequirements: HardwareRequirements - gitHash: string | null + gitHash?: GitHash osVersion: string } diff --git a/sdk/base/lib/osBindings/LanInfo.ts b/sdk/base/lib/osBindings/NetInfo.ts similarity index 80% rename from sdk/base/lib/osBindings/LanInfo.ts rename to sdk/base/lib/osBindings/NetInfo.ts index 59b8a5519..e790cadaa 100644 --- a/sdk/base/lib/osBindings/LanInfo.ts +++ b/sdk/base/lib/osBindings/NetInfo.ts @@ -1,6 +1,7 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type LanInfo = { +export type NetInfo = { + public: boolean assignedPort: number | null assignedSslPort: number | null } diff --git a/sdk/base/lib/osBindings/NetworkInterfaceInfo.ts b/sdk/base/lib/osBindings/NetworkInterfaceInfo.ts new file mode 100644 index 000000000..796046b93 --- /dev/null +++ b/sdk/base/lib/osBindings/NetworkInterfaceInfo.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { IpInfo } from "./IpInfo" + +export type NetworkInterfaceInfo = { + public: boolean | null + ipInfo: IpInfo | null +} diff --git a/sdk/base/lib/osBindings/NetworkInterfaceType.ts b/sdk/base/lib/osBindings/NetworkInterfaceType.ts new file mode 100644 index 000000000..e20067dcc --- /dev/null +++ b/sdk/base/lib/osBindings/NetworkInterfaceType.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type NetworkInterfaceType = "ethernet" | "wireless" | "wireguard" diff --git a/sdk/base/lib/osBindings/PackageVersionInfo.ts b/sdk/base/lib/osBindings/PackageVersionInfo.ts index 80481acb3..c71fd5921 100644 --- a/sdk/base/lib/osBindings/PackageVersionInfo.ts +++ b/sdk/base/lib/osBindings/PackageVersionInfo.ts @@ -3,6 +3,7 @@ import type { Alerts } from "./Alerts" import type { DataUrl } from "./DataUrl" import type { DependencyMetadata } from "./DependencyMetadata" import type { Description } from "./Description" +import type { GitHash } from "./GitHash" import type { HardwareRequirements } from "./HardwareRequirements" import type { MerkleArchiveCommitment } from "./MerkleArchiveCommitment" import type { PackageId } from "./PackageId" @@ -13,7 +14,7 @@ export type PackageVersionInfo = { icon: DataUrl description: Description releaseNotes: string - gitHash: string + gitHash: GitHash license: string wrapperRepo: string upstreamRepo: string diff --git a/sdk/base/lib/osBindings/ServerInfo.ts b/sdk/base/lib/osBindings/ServerInfo.ts index 89d7fc1b0..6eec14745 100644 --- a/sdk/base/lib/osBindings/ServerInfo.ts +++ b/sdk/base/lib/osBindings/ServerInfo.ts @@ -1,8 +1,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AcmeProvider } from "./AcmeProvider" import type { AcmeSettings } from "./AcmeSettings" import type { Governor } from "./Governor" -import type { IpInfo } from "./IpInfo" import type { LshwDevice } from "./LshwDevice" +import type { NetworkInterfaceInfo } from "./NetworkInterfaceInfo" import type { ServerStatus } from "./ServerStatus" import type { SmtpValue } from "./SmtpValue" import type { WifiInfo } from "./WifiInfo" @@ -22,8 +23,8 @@ export type ServerInfo = { * for backwards compatibility */ torAddress: string - ipInfo: { [key: string]: IpInfo } - acme: AcmeSettings | null + networkInterfaces: { [key: string]: NetworkInterfaceInfo } + acme: { [key: AcmeProvider]: AcmeSettings } statusInfo: ServerStatus wifi: WifiInfo unreadNotificationCount: number diff --git a/sdk/base/lib/osBindings/ServiceInterface.ts b/sdk/base/lib/osBindings/ServiceInterface.ts index 9bcec0056..6a58675a4 100644 --- a/sdk/base/lib/osBindings/ServiceInterface.ts +++ b/sdk/base/lib/osBindings/ServiceInterface.ts @@ -7,7 +7,6 @@ export type ServiceInterface = { id: ServiceInterfaceId name: string description: string - hasPrimary: boolean masked: boolean addressInfo: AddressInfo type: ServiceInterfaceType diff --git a/sdk/base/lib/osBindings/SetPublicParams.ts b/sdk/base/lib/osBindings/SetPublicParams.ts new file mode 100644 index 000000000..03bc3082b --- /dev/null +++ b/sdk/base/lib/osBindings/SetPublicParams.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type SetPublicParams = { interface: string; public: boolean | null } diff --git a/sdk/base/lib/osBindings/UnsetPublicParams.ts b/sdk/base/lib/osBindings/UnsetPublicParams.ts new file mode 100644 index 000000000..db8f730e1 --- /dev/null +++ b/sdk/base/lib/osBindings/UnsetPublicParams.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type UnsetPublicParams = { interface: string } diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index f76f595c9..6eff86872 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -1,4 +1,5 @@ export { AcceptSigners } from "./AcceptSigners" +export { AcmeProvider } from "./AcmeProvider" export { AcmeSettings } from "./AcmeSettings" export { ActionId } from "./ActionId" export { ActionInput } from "./ActionInput" @@ -66,6 +67,7 @@ export { DepInfo } from "./DepInfo" export { Description } from "./Description" export { DestroySubcontainerFsParams } from "./DestroySubcontainerFsParams" export { DeviceFilter } from "./DeviceFilter" +export { DomainConfig } from "./DomainConfig" export { Duration } from "./Duration" export { EchoParams } from "./EchoParams" export { EditSignerParams } from "./EditSignerParams" @@ -73,6 +75,7 @@ export { EncryptedWire } from "./EncryptedWire" export { ExportActionParams } from "./ExportActionParams" export { ExportServiceInterfaceParams } from "./ExportServiceInterfaceParams" export { ExposeForDependentsParams } from "./ExposeForDependentsParams" +export { ForgetInterfaceParams } from "./ForgetInterfaceParams" export { FullIndex } from "./FullIndex" export { FullProgress } from "./FullProgress" export { GetActionInputParams } from "./GetActionInputParams" @@ -82,7 +85,6 @@ export { GetOsVersionParams } from "./GetOsVersionParams" export { GetPackageParams } from "./GetPackageParams" export { GetPackageResponseFull } from "./GetPackageResponseFull" export { GetPackageResponse } from "./GetPackageResponse" -export { GetPrimaryUrlParams } from "./GetPrimaryUrlParams" export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams" export { GetServicePortForwardParams } from "./GetServicePortForwardParams" export { GetSslCertificateParams } from "./GetSslCertificateParams" @@ -90,11 +92,11 @@ export { GetSslKeyParams } from "./GetSslKeyParams" export { GetStatusParams } from "./GetStatusParams" export { GetStoreParams } from "./GetStoreParams" export { GetSystemSmtpParams } from "./GetSystemSmtpParams" +export { GitHash } from "./GitHash" export { Governor } from "./Governor" export { Guid } from "./Guid" export { HardwareRequirements } from "./HardwareRequirements" export { HealthCheckId } from "./HealthCheckId" -export { HostAddress } from "./HostAddress" export { HostId } from "./HostId" export { HostKind } from "./HostKind" export { HostnameInfo } from "./HostnameInfo" @@ -112,7 +114,6 @@ export { InstallingState } from "./InstallingState" export { InstallParams } from "./InstallParams" export { IpHostname } from "./IpHostname" export { IpInfo } from "./IpInfo" -export { LanInfo } from "./LanInfo" export { ListPackageSignersParams } from "./ListPackageSignersParams" export { ListServiceInterfacesParams } from "./ListServiceInterfacesParams" export { ListVersionSignersParams } from "./ListVersionSignersParams" @@ -128,6 +129,9 @@ export { MountParams } from "./MountParams" export { MountTarget } from "./MountTarget" export { NamedHealthCheckResult } from "./NamedHealthCheckResult" export { NamedProgress } from "./NamedProgress" +export { NetInfo } from "./NetInfo" +export { NetworkInterfaceInfo } from "./NetworkInterfaceInfo" +export { NetworkInterfaceType } from "./NetworkInterfaceType" export { OnionHostname } from "./OnionHostname" export { OsIndex } from "./OsIndex" export { OsVersionInfoMap } from "./OsVersionInfoMap" @@ -172,6 +176,7 @@ export { SetIconParams } from "./SetIconParams" export { SetMainStatusStatus } from "./SetMainStatusStatus" export { SetMainStatus } from "./SetMainStatus" export { SetNameParams } from "./SetNameParams" +export { SetPublicParams } from "./SetPublicParams" export { SetStoreParams } from "./SetStoreParams" export { SetupExecuteParams } from "./SetupExecuteParams" export { SetupProgress } from "./SetupProgress" @@ -181,6 +186,7 @@ export { SignAssetParams } from "./SignAssetParams" export { SignerInfo } from "./SignerInfo" export { SmtpValue } from "./SmtpValue" export { StartStop } from "./StartStop" +export { UnsetPublicParams } from "./UnsetPublicParams" export { UpdatingState } from "./UpdatingState" export { VerifyCifsParams } from "./VerifyCifsParams" export { VersionSignerParams } from "./VersionSignerParams" diff --git a/sdk/base/lib/test/startosTypeValidation.test.ts b/sdk/base/lib/test/startosTypeValidation.test.ts index 509da0894..2de7b43a4 100644 --- a/sdk/base/lib/test/startosTypeValidation.test.ts +++ b/sdk/base/lib/test/startosTypeValidation.test.ts @@ -26,7 +26,6 @@ import { SetDependenciesParams } from ".././osBindings" import { GetSystemSmtpParams } from ".././osBindings" import { GetServicePortForwardParams } from ".././osBindings" import { ExportServiceInterfaceParams } from ".././osBindings" -import { GetPrimaryUrlParams } from ".././osBindings" import { ListServiceInterfacesParams } from ".././osBindings" import { ExportActionParams } from ".././osBindings" import { MountParams } from ".././osBindings" @@ -83,7 +82,6 @@ describe("startosTypeValidation ", () => { getServicePortForward: {} as GetServicePortForwardParams, clearServiceInterfaces: {} as ClearServiceInterfacesParams, exportServiceInterface: {} as ExportServiceInterfaceParams, - getPrimaryUrl: {} as WithCallback, listServiceInterfaces: {} as WithCallback, mount: {} as MountParams, checkDependencies: {} as CheckDependenciesParam, diff --git a/sdk/base/lib/types.ts b/sdk/base/lib/types.ts index 36d4bd293..85a8c4404 100644 --- a/sdk/base/lib/types.ts +++ b/sdk/base/lib/types.ts @@ -138,33 +138,6 @@ export declare const hostName: unique symbol // asdflkjadsf.onion | 1.2.3.4 export type Hostname = string & { [hostName]: never } -export type HostnameInfoIp = { - kind: "ip" - networkInterfaceId: string - public: boolean - hostname: - | { - kind: "ipv4" | "ipv6" | "local" - value: string - port: number | null - sslPort: number | null - } - | { - kind: "domain" - domain: string - subdomain: string | null - port: number | null - sslPort: number | null - } -} - -export type HostnameInfoOnion = { - kind: "onion" - hostname: { value: string; port: number | null; sslPort: number | null } -} - -export type HostnameInfo = HostnameInfoIp | HostnameInfoOnion - export type ServiceInterfaceId = string export { ServiceInterface } diff --git a/sdk/base/lib/util/getServiceInterface.ts b/sdk/base/lib/util/getServiceInterface.ts index cbbb345cb..2e81e5ee2 100644 --- a/sdk/base/lib/util/getServiceInterface.ts +++ b/sdk/base/lib/util/getServiceInterface.ts @@ -1,15 +1,6 @@ import { ServiceInterfaceType } from "../types" import { knownProtocols } from "../interfaces/Host" -import { - AddressInfo, - Host, - HostAddress, - Hostname, - HostnameInfo, - HostnameInfoIp, - HostnameInfoOnion, - IpInfo, -} from "../types" +import { AddressInfo, Host, Hostname, HostnameInfo } from "../types" import { Effects } from "../Effects" export type UrlString = string @@ -48,8 +39,6 @@ export type ServiceInterfaceFilled = { name: string /** Human readable description, used as tooltip usually */ description: string - /** Whether or not the interface has a primary URL */ - hasPrimary: boolean /** Whether or not to mask the URIs for this interface. Useful if the URIs contain sensitive information, such as a password, macaroon, or API key */ masked: boolean /** Information about the host for this binding */ @@ -58,10 +47,6 @@ export type ServiceInterfaceFilled = { addressInfo: FilledAddressInfo | null /** Indicates if we are a ui/p2p/api for the kind of interface that this is representing */ type: ServiceInterfaceType - /** The primary hostname for the service, as chosen by the user */ - primaryHostname: Hostname | null - /** The primary URL for the service, as chosen by the user */ - primaryUrl: UrlString | null } const either = (...args: ((a: A) => boolean)[]) => @@ -89,7 +74,9 @@ export const addressHostToUrl = ( if (host.hostname.kind === "domain") { hostname = `${host.hostname.subdomain ? `${host.hostname.subdomain}.` : ""}${host.hostname.domain}` } else if (host.hostname.kind === "ipv6") { - hostname = `[${host.hostname.value}]` + hostname = host.hostname.value.startsWith("fe80::") + ? `[${host.hostname.value}%${host.hostname.scopeId}]` + : `[${host.hostname.value}]` } else { hostname = host.hostname.value } @@ -200,23 +187,13 @@ const makeInterfaceFilled = async ({ hostId, callback, }) - const primaryUrl = await effects.getPrimaryUrl({ - hostId, - packageId, - callback, - }) const interfaceFilled: ServiceInterfaceFilled = { ...serviceInterfaceValue, - primaryUrl: primaryUrl, host, addressInfo: host ? filledAddress(host, serviceInterfaceValue.addressInfo) : null, - get primaryHostname() { - if (primaryUrl == null) return null - return getHostname(primaryUrl) - }, } return interfaceFilled } diff --git a/sdk/base/lib/util/getServiceInterfaces.ts b/sdk/base/lib/util/getServiceInterfaces.ts index 1d83684d6..faeb508b4 100644 --- a/sdk/base/lib/util/getServiceInterfaces.ts +++ b/sdk/base/lib/util/getServiceInterfaces.ts @@ -30,22 +30,10 @@ const makeManyInterfaceFilled = async ({ if (!host) { throw new Error(`host ${hostId} not found!`) } - const primaryUrl = await effects - .getPrimaryUrl({ - hostId, - packageId, - callback, - }) - .catch(() => null) return { ...serviceInterfaceValue, - primaryUrl: primaryUrl, host, addressInfo: filledAddress(host, serviceInterfaceValue.addressInfo), - get primaryHostname() { - if (primaryUrl == null) return null - return getHostname(primaryUrl) - }, } }), ) diff --git a/sdk/base/lib/util/patterns.ts b/sdk/base/lib/util/patterns.ts index 2c9c7010d..c117c89e5 100644 --- a/sdk/base/lib/util/patterns.ts +++ b/sdk/base/lib/util/patterns.ts @@ -2,58 +2,58 @@ import { Pattern } from "../actions/input/inputSpecTypes" import * as regexes from "./regexes" export const ipv6: Pattern = { - regex: regexes.ipv6.toString(), + regex: regexes.ipv6.source, description: "Must be a valid IPv6 address", } export const ipv4: Pattern = { - regex: regexes.ipv4.toString(), + regex: regexes.ipv4.source, description: "Must be a valid IPv4 address", } export const hostname: Pattern = { - regex: regexes.hostname.toString(), + regex: regexes.hostname.source, description: "Must be a valid hostname", } export const localHostname: Pattern = { - regex: regexes.localHostname.toString(), + regex: regexes.localHostname.source, description: 'Must be a valid ".local" hostname', } export const torHostname: Pattern = { - regex: regexes.torHostname.toString(), + regex: regexes.torHostname.source, description: 'Must be a valid Tor (".onion") hostname', } export const url: Pattern = { - regex: regexes.url.toString(), + regex: regexes.url.source, description: "Must be a valid URL", } export const localUrl: Pattern = { - regex: regexes.localUrl.toString(), + regex: regexes.localUrl.source, description: 'Must be a valid ".local" URL', } export const torUrl: Pattern = { - regex: regexes.torUrl.toString(), + regex: regexes.torUrl.source, description: 'Must be a valid Tor (".onion") URL', } export const ascii: Pattern = { - regex: regexes.ascii.toString(), + regex: regexes.ascii.source, description: "May only contain ASCII characters. See https://www.w3schools.com/charsets/ref_html_ascii.asp", } export const email: Pattern = { - regex: regexes.email.toString(), + regex: regexes.email.source, description: "Must be a valid email address", } export const base64: Pattern = { - regex: regexes.base64.toString(), + regex: regexes.base64.source, description: "May only contain base64 characters. See https://base64.guru/learn/base64-characters", } diff --git a/sdk/base/package-lock.json b/sdk/base/package-lock.json index d7b491303..4d5625489 100644 --- a/sdk/base/package-lock.json +++ b/sdk/base/package-lock.json @@ -14,7 +14,7 @@ "isomorphic-fetch": "^3.0.0", "lodash.merge": "^4.6.2", "mime-types": "^2.1.35", - "ts-matches": "^6.1.0", + "ts-matches": "^6.2.1", "yaml": "^2.2.2" }, "devDependencies": { @@ -3897,9 +3897,9 @@ "dev": true }, "node_modules/ts-matches": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.1.0.tgz", - "integrity": "sha512-01qvbIpOiKdbzzXDH84JeHunvCwBGFdZw94jS6kOGLSN5ms+1nBZtfe8WSuYMIPb1xPA+qyAiVgznFi2VCQ6UQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.2.1.tgz", + "integrity": "sha512-qdnMgTHsGCEGGK6QiaNMY2vD9eQtRp2Q+pAxcOAzxHJKDKTBYsc1ISTg1zp8H2+EmtCB0eko/1TwYUA5/mUGug==", "license": "MIT" }, "node_modules/ts-morph": { diff --git a/sdk/base/package.json b/sdk/base/package.json index 4cc2fc7ca..6eae719a7 100644 --- a/sdk/base/package.json +++ b/sdk/base/package.json @@ -27,7 +27,7 @@ "isomorphic-fetch": "^3.0.0", "lodash.merge": "^4.6.2", "mime-types": "^2.1.35", - "ts-matches": "^6.1.0", + "ts-matches": "^6.2.1", "yaml": "^2.2.2" }, "prettier": { diff --git a/sdk/package/lib/StartSdk.ts b/sdk/package/lib/StartSdk.ts index e7e87f963..65ef23883 100644 --- a/sdk/package/lib/StartSdk.ts +++ b/sdk/package/lib/StartSdk.ts @@ -102,7 +102,6 @@ export class StartSdk { | "clearServiceInterfaces" | "bind" | "getHostInfo" - | "getPrimaryUrl" type MainUsedEffects = "setMainStatus" | "setHealth" type CallbackEffects = "constRetry" | "clearCallbacks" type AlreadyExposed = "getSslCertificate" | "getSystemSmtp" @@ -379,7 +378,6 @@ export class StartSdk { id: 'ui', description: 'The primary web app for this service.', type: 'ui', - hasPrimary: false, masked: false, schemeOverride: null, username: null, @@ -397,8 +395,6 @@ export class StartSdk { id: string /** The human readable description. */ description: string - /** No effect until StartOS v0.4.0. If true, forces the user to select one URL (i.e. .onion, .local, or IP address) as the primary URL. This is needed by some services to function properly. */ - hasPrimary: boolean /** Affects how the interface appears to the user. One of: 'ui', 'api', 'p2p'. If 'ui', the user will see a "Launch UI" button */ type: ServiceInterfaceType /** (optional) prepends the provided username to all URLs. */ @@ -562,7 +558,6 @@ export class StartSdk { id: 'primary-ui', description: 'The primary web app for this service.', type: 'ui', - hasPrimary: false, masked: false, schemeOverride: null, username: null, @@ -575,7 +570,6 @@ export class StartSdk { id: 'admin-ui', description: 'The admin web app for this service.', type: 'ui', - hasPrimary: false, masked: false, schemeOverride: null, username: null, @@ -596,7 +590,6 @@ export class StartSdk { id: 'api', description: 'The advanced API for this service.', type: 'api', - hasPrimary: false, masked: false, schemeOverride: null, username: null, @@ -688,6 +681,18 @@ export class StartSdk { return Daemons.of({ effects, started, healthReceipts }) }, }, + SubContainer: { + of( + effects: Effects, + image: { + id: T.ImageId & keyof Manifest["images"] + sharedRun?: boolean + }, + name: string, + ) { + return SubContainer.of(effects, image, name) + }, + }, List: { /** * @description Create a list of text inputs. @@ -1269,7 +1274,6 @@ export class StartSdk { * @example default: 'radio1' */ default: keyof Variants & string - required: boolean /** * @description A mapping of unique radio options to their human readable display format. * @example diff --git a/sdk/package/lib/mainFn/CommandController.ts b/sdk/package/lib/mainFn/CommandController.ts index 3b2285adb..498de2843 100644 --- a/sdk/package/lib/mainFn/CommandController.ts +++ b/sdk/package/lib/mainFn/CommandController.ts @@ -60,51 +60,59 @@ export class CommandController { } return subc })() - let childProcess: cp.ChildProcess - if (options.runAsInit) { - childProcess = await subc.launch(commands, { - env: options.env, - }) - } else { - childProcess = await subc.spawn(commands, { - env: options.env, - stdio: options.onStdout || options.onStderr ? "pipe" : "inherit", + + try { + let childProcess: cp.ChildProcess + if (options.runAsInit) { + childProcess = await subc.launch(commands, { + env: options.env, + }) + } else { + childProcess = await subc.spawn(commands, { + env: options.env, + stdio: options.onStdout || options.onStderr ? "pipe" : "inherit", + }) + } + + if (options.onStdout) childProcess.stdout?.on("data", options.onStdout) + if (options.onStderr) childProcess.stderr?.on("data", options.onStderr) + + const state = { exited: false } + const answer = new Promise((resolve, reject) => { + childProcess.on("exit", (code) => { + state.exited = true + if ( + code === 0 || + code === 143 || + (code === null && childProcess.signalCode == "SIGTERM") + ) { + return resolve(null) + } + if (code) { + return reject( + new Error(`${commands[0]} exited with code ${code}`), + ) + } else { + return reject( + new Error( + `${commands[0]} exited with signal ${childProcess.signalCode}`, + ), + ) + } + }) }) + + return new CommandController( + answer, + state, + subc, + childProcess, + options.sigtermTimeout, + ) + } catch (e) { + await subc.destroy() + throw e } - - if (options.onStdout) childProcess.stdout?.on("data", options.onStdout) - if (options.onStderr) childProcess.stderr?.on("data", options.onStderr) - - const state = { exited: false } - const answer = new Promise((resolve, reject) => { - childProcess.on("exit", (code) => { - state.exited = true - if ( - code === 0 || - code === 143 || - (code === null && childProcess.signalCode == "SIGTERM") - ) { - return resolve(null) - } - if (code) { - return reject(new Error(`${commands[0]} exited with code ${code}`)) - } else { - return reject( - new Error( - `${commands[0]} exited with signal ${childProcess.signalCode}`, - ), - ) - } - }) - }) - - return new CommandController( - answer, - state, - subc, - childProcess, - options.sigtermTimeout, - ) } } get subContainerHandle() { @@ -121,7 +129,7 @@ export class CommandController { if (!this.state.exited) { this.process.kill("SIGKILL") } - await this.subcontainer.destroy?.().catch((_) => {}) + await this.subcontainer.destroy().catch((_) => {}) } } async term({ signal = SIGTERM, timeout = this.sigtermTimeout } = {}) { @@ -141,7 +149,7 @@ export class CommandController { await this.runningAnswer } finally { - await this.subcontainer.destroy?.() + await this.subcontainer.destroy() } } } diff --git a/sdk/package/lib/mainFn/Daemon.ts b/sdk/package/lib/mainFn/Daemon.ts index d9db89b6a..0cbc9cd94 100644 --- a/sdk/package/lib/mainFn/Daemon.ts +++ b/sdk/package/lib/mainFn/Daemon.ts @@ -60,6 +60,8 @@ export class Daemon { let timeoutCounter = 0 new Promise(async () => { while (this.shouldBeRunning) { + if (this.commandController) + await this.commandController.term().catch((err) => console.error(err)) this.commandController = await this.startCommand() await this.commandController.wait().catch((err) => console.error(err)) await new Promise((resolve) => setTimeout(resolve, timeoutCounter)) diff --git a/sdk/package/lib/mainFn/Daemons.ts b/sdk/package/lib/mainFn/Daemons.ts index 495e6c527..e18fa2314 100644 --- a/sdk/package/lib/mainFn/Daemons.ts +++ b/sdk/package/lib/mainFn/Daemons.ts @@ -5,7 +5,7 @@ import { HealthCheckResult } from "../health/checkFns" import { Trigger } from "../trigger" import * as T from "../../../base/lib/types" import { Mounts } from "./Mounts" -import { ExecSpawnable, MountOptions } from "../util/SubContainer" +import { ExecSpawnable, MountOptions, SubContainer } from "../util/SubContainer" import { promisify } from "node:util" import * as CP from "node:child_process" @@ -49,16 +49,18 @@ type DaemonsParams< > = { /** The command line command to start the daemon */ command: T.CommandType - /** Information about the image in which the daemon runs */ - image: { - /** The ID of the image. Must be one of the image IDs declared in the manifest */ - id: keyof Manifest["images"] & T.ImageId - /** - * Whether or not to share the `/run` directory with the parent container. - * This is useful if you are trying to connect to a service that exposes a unix domain socket or auth cookie via the `/run` directory - */ - sharedRun?: boolean - } + /** Information about the subcontainer in which the daemon runs */ + subcontainer: + | { + /** The ID of the image. Must be one of the image IDs declared in the manifest */ + id: keyof Manifest["images"] & T.ImageId + /** + * Whether or not to share the `/run` directory with the parent container. + * This is useful if you are trying to connect to a service that exposes a unix domain socket or auth cookie via the `/run` directory + */ + sharedRun?: boolean + } + | SubContainer /** For mounting the necessary volumes. Syntax: sdk.Mounts.of().addVolume() */ mounts: Mounts env?: Record @@ -147,11 +149,16 @@ export class Daemons options: DaemonsParams, ) { const daemonIndex = this.daemons.length - const daemon = Daemon.of()(this.effects, options.image, options.command, { - ...options, - mounts: options.mounts.build(), - subcontainerName: id, - }) + const daemon = Daemon.of()( + this.effects, + options.subcontainer, + options.command, + { + ...options, + mounts: options.mounts.build(), + subcontainerName: id, + }, + ) const healthDaemon = new HealthDaemon( daemon, daemonIndex, @@ -178,14 +185,18 @@ export class Daemons } async build() { - this.updateMainHealth() - this.healthDaemons.forEach((x) => - x.addWatcher(() => this.updateMainHealth()), - ) const built = { - term: async (options?: { signal?: Signals; timeout?: number }) => { + term: async () => { try { - await Promise.all(this.healthDaemons.map((x) => x.term(options))) + for (let result of await Promise.allSettled( + this.healthDaemons.map((x) => + x.term({ timeout: x.sigtermTimeout }), + ), + )) { + if (result.status === "rejected") { + console.error(result.reason) + } + } } finally { this.effects.setMainStatus({ status: "stopped" }) } @@ -194,8 +205,4 @@ export class Daemons this.started(() => built.term()) return built } - - private updateMainHealth() { - this.effects.setMainStatus({ status: "running" }) - } } diff --git a/sdk/package/lib/mainFn/HealthDaemon.ts b/sdk/package/lib/mainFn/HealthDaemon.ts index b66e3e406..ac459f08c 100644 --- a/sdk/package/lib/mainFn/HealthDaemon.ts +++ b/sdk/package/lib/mainFn/HealthDaemon.ts @@ -25,6 +25,8 @@ export class HealthDaemon { private _health: HealthCheckResult = { result: "starting", message: null } private healthWatchers: Array<() => unknown> = [] private running = false + private resolveReady: (() => void) | undefined + private readyPromise: Promise constructor( private readonly daemon: Promise, readonly daemonIndex: number, @@ -35,6 +37,7 @@ export class HealthDaemon { readonly effects: Effects, readonly sigtermTimeout: number = DEFAULT_SIGTERM_TIMEOUT, ) { + this.readyPromise = new Promise((resolve) => (this.resolveReady = resolve)) this.updateStatus() this.dependencies.forEach((d) => d.addWatcher(() => this.updateStatus())) } @@ -112,6 +115,12 @@ export class HealthDaemon { message: "message" in err ? err.message : String(err), } }) + if ( + this.resolveReady && + (response.result === "success" || response.result === "disabled") + ) { + this.resolveReady() + } await this.setHealth(response) } else { await this.setHealth({ @@ -129,6 +138,10 @@ export class HealthDaemon { } } + onReady() { + return this.readyPromise + } + private async setHealth(health: HealthCheckResult) { this._health = health this.healthWatchers.forEach((watcher) => watcher()) diff --git a/sdk/package/lib/manifest/setupManifest.ts b/sdk/package/lib/manifest/setupManifest.ts index 1a78c062c..3cd4f8bfb 100644 --- a/sdk/package/lib/manifest/setupManifest.ts +++ b/sdk/package/lib/manifest/setupManifest.ts @@ -26,16 +26,6 @@ export function setupManifest< return manifest } -function gitHash(): string { - const hash = execSync("git rev-parse HEAD").toString().trim() - try { - execSync("git diff-index --quiet HEAD --") - return hash - } catch (e) { - return hash + "-modified" - } -} - export function buildManifest< Id extends string, Version extends string, @@ -68,7 +58,6 @@ export function buildManifest< ) return { ...manifest, - gitHash: gitHash(), osVersion: SDKVersion, version: versions.current.options.version, releaseNotes: versions.current.options.releaseNotes, diff --git a/sdk/package/lib/test/host.test.ts b/sdk/package/lib/test/host.test.ts index 87f22b8bd..4492804ec 100644 --- a/sdk/package/lib/test/host.test.ts +++ b/sdk/package/lib/test/host.test.ts @@ -15,7 +15,6 @@ describe("host", () => { name: "Foo", id: "foo", description: "A Foo", - hasPrimary: false, type: "ui", username: "bar", path: "/baz", diff --git a/sdk/package/package-lock.json b/sdk/package/package-lock.json index 9abc963fb..58a37e357 100644 --- a/sdk/package/package-lock.json +++ b/sdk/package/package-lock.json @@ -1,12 +1,12 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.0", + "version": "0.3.6-beta.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.0", + "version": "0.3.6-beta.3", "license": "MIT", "dependencies": { "@iarna/toml": "^2.2.5", @@ -15,7 +15,7 @@ "isomorphic-fetch": "^3.0.0", "lodash.merge": "^4.6.2", "mime-types": "^2.1.35", - "ts-matches": "^6.1.0", + "ts-matches": "^6.2.1", "yaml": "^2.2.2" }, "devDependencies": { @@ -3918,9 +3918,9 @@ "dev": true }, "node_modules/ts-matches": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.1.0.tgz", - "integrity": "sha512-01qvbIpOiKdbzzXDH84JeHunvCwBGFdZw94jS6kOGLSN5ms+1nBZtfe8WSuYMIPb1xPA+qyAiVgznFi2VCQ6UQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-6.2.1.tgz", + "integrity": "sha512-qdnMgTHsGCEGGK6QiaNMY2vD9eQtRp2Q+pAxcOAzxHJKDKTBYsc1ISTg1zp8H2+EmtCB0eko/1TwYUA5/mUGug==", "license": "MIT" }, "node_modules/ts-morph": { diff --git a/sdk/package/package.json b/sdk/package/package.json index a5bb78159..1a68b9d1b 100644 --- a/sdk/package/package.json +++ b/sdk/package/package.json @@ -1,6 +1,6 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.0", + "version": "0.3.6-beta.3", "description": "Software development kit to facilitate packaging services for StartOS", "main": "./package/lib/index.js", "types": "./package/lib/index.d.ts", @@ -33,7 +33,7 @@ "isomorphic-fetch": "^3.0.0", "lodash.merge": "^4.6.2", "mime-types": "^2.1.35", - "ts-matches": "^6.1.0", + "ts-matches": "^6.2.1", "yaml": "^2.2.2", "@iarna/toml": "^2.2.5", "@noble/curves": "^1.4.0", diff --git a/web/package-lock.json b/web/package-lock.json index 5652a0406..1c34d8dc8 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.9", + "version": "0.3.6-alpha.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.3.6-alpha.9", + "version": "0.3.6-alpha.10", "license": "MIT", "dependencies": { "@angular/animations": "^14.1.0", diff --git a/web/package.json b/web/package.json index ecc253904..d71b2f0a2 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.9", + "version": "0.3.6-alpha.10", "author": "Start9 Labs, Inc", "homepage": "https://start9.com/", "license": "MIT", diff --git a/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts b/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts index 0b31dce4b..ca8645f18 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts @@ -121,9 +121,34 @@ function getAddresses( ): MappedAddress[] { const addressInfo = serviceInterface.addressInfo - const hostnames = + let hostnames = host.kind === 'multi' ? host.hostnameInfo[addressInfo.internalPort] : [] + hostnames = hostnames.filter( + h => + window.location.host === 'localhost' || + h.kind !== 'ip' || + h.hostname.kind !== 'ipv6' || + !h.hostname.value.startsWith('fe80::'), + ) + if (window.location.host === 'localhost') { + const local = hostnames.find( + h => h.kind === 'ip' && h.hostname.kind === 'local', + ) + if (local) { + hostnames.unshift({ + kind: 'ip', + networkInterfaceId: 'lo', + public: false, + hostname: { + kind: 'local', + port: local.hostname.port, + sslPort: local.hostname.sslPort, + value: 'localhost', + }, + }) + } + } const addressesWithNames = hostnames.flatMap(h => { let name = '' @@ -144,14 +169,14 @@ function getAddresses( const addresses = utils.addressHostToUrl(addressInfo, h) if (addresses.length > 1) { - return utils.addressHostToUrl(addressInfo, h).map(url => ({ + return addresses.map(url => ({ name: `${name} (${new URL(url).protocol .replace(':', '') .toUpperCase()})`, url, })) } else { - return utils.addressHostToUrl(addressInfo, h).map(url => ({ + return addresses.map(url => ({ name, url, })) diff --git a/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.html b/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.html index 03d7ef3d7..c7bdf6a2a 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.html +++ b/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.html @@ -58,25 +58,28 @@ - - - -

{{ iface.key }} (IPv4)

-

{{ ipv4 || 'n/a' }}

-
- - - -
- - -

{{ iface.key }} (IPv6)

-

{{ ipv6 || 'n/a' }}

-
- - - -
+ + + + + + +

{{ iface.key }} ({{ ipAddr.includes("::") ? "IPv6" : "IPv4" }})

+

{{ + ipAddr.includes("fe80::") + ? "[" + ipAddr + "%" + iface.value.ipInfo.scopeId + "]" + : ipAddr.includes("::") + ? "[" + ipAddr + "]" + : ipAddr + }}

+
+ + + +
+
+
+
Device Credentials diff --git a/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.ts b/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.ts index 0055ff6c1..6c7b41399 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-specs/server-specs.page.ts @@ -14,6 +14,7 @@ import { DataModel } from 'src/app/services/patch-db/data-model' }) export class ServerSpecsPage { readonly server$ = this.patch.watch$('serverInfo') + readonly isLocalhost = window.location.host === 'localhost' constructor( private readonly toastCtrl: ToastController, diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index a3562caa6..a91976493 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -1721,7 +1721,6 @@ export module Mock { serviceInterfaces: { ui: { id: 'ui', - hasPrimary: false, masked: false, name: 'Web UI', description: @@ -1738,7 +1737,6 @@ export module Mock { }, rpc: { id: 'rpc', - hasPrimary: false, masked: false, name: 'RPC', description: @@ -1755,7 +1753,6 @@ export module Mock { }, p2p: { id: 'p2p', - hasPrimary: true, masked: false, name: 'P2P', description: @@ -1776,7 +1773,8 @@ export module Mock { abcdefg: { kind: 'multi', bindings: [], - addresses: [], + onions: [], + domains: {}, hostnameInfo: { 80: [ { @@ -1829,7 +1827,8 @@ export module Mock { public: false, hostname: { kind: 'ipv6', - value: '[FE80:CD00:0000:0CDE:1257:0000:211E:729CD]', + value: '[fe80:cd00:0000:0cde:1257:0000:211e:72cd]', + scopeId: 2, port: null, sslPort: 1234, }, @@ -1840,7 +1839,8 @@ export module Mock { public: false, hostname: { kind: 'ipv6', - value: '[FE80:CD00:0000:0CDE:1257:0000:211E:1234]', + value: '[fe80:cd00:0000:0cde:1257:0000:211e:1234]', + scopeId: 3, port: null, sslPort: 1234, }, @@ -1859,7 +1859,8 @@ export module Mock { bcdefgh: { kind: 'multi', bindings: [], - addresses: [], + onions: [], + domains: {}, hostnameInfo: { 8332: [], }, @@ -1867,7 +1868,8 @@ export module Mock { cdefghi: { kind: 'multi', bindings: [], - addresses: [], + onions: [], + domains: {}, hostnameInfo: { 8333: [], }, @@ -1914,7 +1916,6 @@ export module Mock { serviceInterfaces: { ui: { id: 'ui', - hasPrimary: false, masked: false, name: 'Web UI', description: 'A launchable web app for Bitcoin Proxy', @@ -1960,7 +1961,6 @@ export module Mock { serviceInterfaces: { grpc: { id: 'grpc', - hasPrimary: false, masked: false, name: 'GRPC', description: @@ -1977,7 +1977,6 @@ export module Mock { }, lndconnect: { id: 'lndconnect', - hasPrimary: false, masked: true, name: 'LND Connect', description: @@ -1994,7 +1993,6 @@ export module Mock { }, p2p: { id: 'p2p', - hasPrimary: true, masked: false, name: 'P2P', description: diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index 81e316b56..4e7928581 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -41,21 +41,32 @@ export const mockPatchData: DataModel = { lastBackup: new Date(new Date().valueOf() - 604800001).toISOString(), lanAddress: 'https://adjective-noun.local', torAddress: 'https://myveryownspecialtoraddress.onion', - ipInfo: { + networkInterfaces: { eth0: { - ipv4: '10.0.0.1', - ipv4Range: '10.0.0.1/24', - ipv6: null, - ipv6Range: null, + public: false, + ipInfo: { + scopeId: 1, + deviceType: 'ethernet', + subnets: ['10.0.0.1/24'], + wanIp: null, + ntpServers: [], + }, }, wlan0: { - ipv4: '10.0.90.12', - ipv4Range: '10.0.90.12/24', - ipv6: 'FE80:CD00:0000:0CDE:1257:0000:211E:729CD', - ipv6Range: 'FE80:CD00:0000:0CDE:1257:0000:211E:729CD/64', + public: false, + ipInfo: { + scopeId: 2, + deviceType: 'wireless', + subnets: [ + '10.0.90.12/24', + 'FE80:CD00:0000:0CDE:1257:0000:211E:729CD/64', + ], + wanIp: null, + ntpServers: [], + }, }, }, - acme: null, + acme: {}, unreadNotificationCount: 4, // password is asdfasdf passwordHash: @@ -140,7 +151,6 @@ export const mockPatchData: DataModel = { serviceInterfaces: { ui: { id: 'ui', - hasPrimary: false, masked: false, name: 'Web UI', description: @@ -157,7 +167,6 @@ export const mockPatchData: DataModel = { }, rpc: { id: 'rpc', - hasPrimary: false, masked: false, name: 'RPC', description: @@ -174,7 +183,6 @@ export const mockPatchData: DataModel = { }, p2p: { id: 'p2p', - hasPrimary: true, masked: false, name: 'P2P', description: @@ -195,7 +203,8 @@ export const mockPatchData: DataModel = { abcdefg: { kind: 'multi', bindings: [], - addresses: [], + onions: [], + domains: {}, hostnameInfo: { 80: [ { @@ -248,7 +257,8 @@ export const mockPatchData: DataModel = { public: false, hostname: { kind: 'ipv6', - value: '[FE80:CD00:0000:0CDE:1257:0000:211E:729CD]', + value: '[fe80:cd00:0000:0cde:1257:0000:211e:72cd]', + scopeId: 2, port: null, sslPort: 1234, }, @@ -259,7 +269,8 @@ export const mockPatchData: DataModel = { public: false, hostname: { kind: 'ipv6', - value: '[FE80:CD00:0000:0CDE:1257:0000:211E:1234]', + value: '[fe80:cd00:0000:0cde:1257:0000:211e:1234]', + scopeId: 3, port: null, sslPort: 1234, }, @@ -278,7 +289,8 @@ export const mockPatchData: DataModel = { bcdefgh: { kind: 'multi', bindings: [], - addresses: [], + onions: [], + domains: {}, hostnameInfo: { 8332: [], }, @@ -286,7 +298,8 @@ export const mockPatchData: DataModel = { cdefghi: { kind: 'multi', bindings: [], - addresses: [], + onions: [], + domains: {}, hostnameInfo: { 8333: [], }, @@ -335,7 +348,6 @@ export const mockPatchData: DataModel = { serviceInterfaces: { grpc: { id: 'grpc', - hasPrimary: false, masked: false, name: 'GRPC', description: @@ -352,7 +364,6 @@ export const mockPatchData: DataModel = { }, lndconnect: { id: 'lndconnect', - hasPrimary: false, masked: true, name: 'LND Connect', description: @@ -369,7 +380,6 @@ export const mockPatchData: DataModel = { }, p2p: { id: 'p2p', - hasPrimary: true, masked: false, name: 'P2P', description: From eb1f3a0ced982d16d0d77eef0cb9b8b1a0fc54e0 Mon Sep 17 00:00:00 2001 From: Remco Ros Date: Fri, 10 Jan 2025 00:40:41 +0100 Subject: [PATCH 07/35] sdk: checkPortListening: check tcp6/udp6 ports (#2763) * sdk: checkPortListening: check tcp6/udp6 ports * allow ipv6 if unspecified address --------- Co-authored-by: Aiden McClelland --- .../lib/health/checkFns/checkPortListening.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sdk/package/lib/health/checkFns/checkPortListening.ts b/sdk/package/lib/health/checkFns/checkPortListening.ts index 0d6792b86..59cd9717f 100644 --- a/sdk/package/lib/health/checkFns/checkPortListening.ts +++ b/sdk/package/lib/health/checkFns/checkPortListening.ts @@ -6,16 +6,17 @@ import * as CP from "node:child_process" const cpExec = promisify(CP.exec) -export function containsAddress(x: string, port: number) { +export function containsAddress(x: string, port: number, address?: bigint) { const readPorts = x .split("\n") .filter(Boolean) .splice(1) - .map((x) => x.split(" ").filter(Boolean)[1]?.split(":")?.[1]) - .filter(Boolean) - .map((x) => Number.parseInt(x, 16)) - .filter(Number.isFinite) - return readPorts.indexOf(port) >= 0 + .map((x) => x.split(" ").filter(Boolean)[1]?.split(":")) + .filter((x) => x?.length > 1) + .map(([addr, p]) => [BigInt(`0x${addr}`), Number.parseInt(p, 16)] as const) + return !!readPorts.find( + ([addr, p]) => (address === undefined || address === addr) && port === p, + ) } /** @@ -39,9 +40,19 @@ export async function checkPortListening( await cpExec(`cat /proc/net/tcp`, {}).then(stringFromStdErrOut), port, ) || + containsAddress( + await cpExec(`cat /proc/net/tcp6`, {}).then(stringFromStdErrOut), + port, + BigInt(0), + ) || containsAddress( await cpExec("cat /proc/net/udp", {}).then(stringFromStdErrOut), port, + ) || + containsAddress( + await cpExec("cat /proc/net/udp6", {}).then(stringFromStdErrOut), + port, + BigInt(0), ) if (hasAddress) { return { result: "success", message: options.successMessage } From 5d759f810ca02cea240392d593afded852165a7e Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Tue, 14 Jan 2025 03:39:52 +0000 Subject: [PATCH 08/35] Bugfix/websockets (#2808) * retry logic for init status * fix login flashing and sideload hanging * add logging * misc backend bugfixes * use closingObserver instead * always show reinstall button * go back to endWith * show error if sideload fails * refactor more watch channels * navigate to services page on sideload complete * handle error closure events properly * handle error scenario better in sideload websocket * remove a clone --------- Co-authored-by: Matt Hill --- core/startos/src/context/setup.rs | 37 +++-- core/startos/src/db/mod.rs | 29 ++-- core/startos/src/install/mod.rs | 49 +++--- core/startos/src/logs.rs | 47 +++--- core/startos/src/net/forward.rs | 31 ++-- core/startos/src/net/network_interface.rs | 54 ++----- core/startos/src/net/web_server.rs | 126 +++++++--------- core/startos/src/service/service_actor.rs | 4 +- core/startos/src/update/mod.rs | 26 ++-- core/startos/src/util/net.rs | 21 +-- core/startos/src/util/sync.rs | 141 ++++++++++++++++++ .../src/version/update_details/v0_3_6.md | 29 ++-- web/projects/ui/src/app/app-routing.module.ts | 2 +- .../ui/src/app/pages/init/init.service.ts | 54 +++---- .../marketplace-show-controls.component.html | 20 ++- .../marketplace-show-controls.component.ts | 4 - .../server-routes/sideload/sideload.page.ts | 9 +- .../sideload/sideload.service.ts | 39 ++++- .../app/services/api/embassy-api.service.ts | 3 +- .../services/api/embassy-live-api.service.ts | 4 +- .../services/api/embassy-mock-api.service.ts | 11 +- .../ui/src/app/services/auth.service.ts | 4 +- 22 files changed, 451 insertions(+), 293 deletions(-) diff --git a/core/startos/src/context/setup.rs b/core/startos/src/context/setup.rs index 30ca1ad39..5c2bf8bfc 100644 --- a/core/startos/src/context/setup.rs +++ b/core/startos/src/context/setup.rs @@ -1,5 +1,5 @@ use std::ops::Deref; -use std::path::{Path}; +use std::path::Path; use std::sync::Arc; use std::time::Duration; @@ -162,21 +162,30 @@ impl SetupContext { if let Err(e) = async { let mut stream = progress_tracker.stream(Some(Duration::from_millis(100))); - while let Some(progress) = stream.next().await { - ws.send(ws::Message::Text( - serde_json::to_string(&progress) - .with_kind(ErrorKind::Serialization)?, - )) - .await - .with_kind(ErrorKind::Network)?; - if progress.overall.is_complete() { - break; + loop { + tokio::select! { + progress = stream.next() => { + if let Some(progress) = progress { + ws.send(ws::Message::Text( + serde_json::to_string(&progress) + .with_kind(ErrorKind::Serialization)?, + )) + .await + .with_kind(ErrorKind::Network)?; + if progress.overall.is_complete() { + return ws.normal_close("complete").await; + } + } else { + return ws.normal_close("complete").await; + } + } + msg = ws.recv() => { + if msg.transpose().with_kind(ErrorKind::Network)?.is_none() { + return Ok(()) + } + } } } - - ws.normal_close("complete").await?; - - Ok::<_, Error>(()) } .await { diff --git a/core/startos/src/db/mod.rs b/core/startos/src/db/mod.rs index c7e38e81c..135153935 100644 --- a/core/startos/src/db/mod.rs +++ b/core/startos/src/db/mod.rs @@ -198,17 +198,26 @@ pub async fn subscribe( session, |mut ws| async move { if let Err(e) = async { - while let Some(rev) = sub.recv().await { - ws.send(ws::Message::Text( - serde_json::to_string(&rev).with_kind(ErrorKind::Serialization)?, - )) - .await - .with_kind(ErrorKind::Network)?; + loop { + tokio::select! { + rev = sub.recv() => { + if let Some(rev) = rev { + ws.send(ws::Message::Text( + serde_json::to_string(&rev).with_kind(ErrorKind::Serialization)?, + )) + .await + .with_kind(ErrorKind::Network)?; + } else { + return ws.normal_close("complete").await; + } + } + msg = ws.recv() => { + if msg.transpose().with_kind(ErrorKind::Network)?.is_none() { + return Ok(()) + } + } + } } - - ws.normal_close("complete").await?; - - Ok::<_, Error>(()) } .await { diff --git a/core/startos/src/install/mod.rs b/core/startos/src/install/mod.rs index bc971da37..33c2ea6c7 100644 --- a/core/startos/src/install/mod.rs +++ b/core/startos/src/install/mod.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use std::path::PathBuf; use std::time::Duration; +use axum::extract::ws; use clap::builder::ValueParserFactory; use clap::{value_parser, CommandFactory, FromArgMatches, Parser}; use color_eyre::eyre::eyre; @@ -12,7 +13,7 @@ use itertools::Itertools; use models::{FromStrParser, VersionString}; use reqwest::header::{HeaderMap, CONTENT_LENGTH}; use reqwest::Url; -use rpc_toolkit::yajrc::{GenericRpcMethod, RpcError}; +use rpc_toolkit::yajrc::RpcError; use rpc_toolkit::HandlerArgs; use rustyline_async::ReadlineEvent; use serde::{Deserialize, Serialize}; @@ -188,7 +189,7 @@ pub async fn sideload( SideloadParams { session }: SideloadParams, ) -> Result { let (upload, file) = upload(&ctx, session.clone()).await?; - let (err_send, err_recv) = oneshot::channel::(); + let (err_send, mut err_recv) = oneshot::channel::(); let progress = Guid::new(); let progress_tracker = FullProgressTracker::new(); let mut progress_listener = progress_tracker.stream(Some(Duration::from_millis(200))); @@ -198,40 +199,44 @@ pub async fn sideload( RpcContinuation::ws_authed( &ctx, session, - |mut ws| { - use axum::extract::ws::Message; - async move { - if let Err(e) = async { + |mut ws| async move { + if let Err(e) = async { + loop { tokio::select! { - res = async { - while let Some(progress) = progress_listener.next().await { - ws.send(Message::Text( + progress = progress_listener.next() => { + if let Some(progress) = progress { + ws.send(ws::Message::Text( serde_json::to_string(&progress) .with_kind(ErrorKind::Serialization)?, )) .await .with_kind(ErrorKind::Network)?; + if progress.overall.is_complete() { + return ws.normal_close("complete").await; + } + } else { + return ws.normal_close("complete").await; } - Ok::<_, Error>(()) - } => res?, - err = err_recv => { + } + msg = ws.recv() => { + if msg.transpose().with_kind(ErrorKind::Network)?.is_none() { + return Ok(()) + } + } + err = (&mut err_recv) => { if let Ok(e) = err { ws.close_result(Err::<&str, _>(e.clone_output())).await?; return Err(e) } } } - - ws.normal_close("complete").await?; - - Ok::<_, Error>(()) - } - .await - { - tracing::error!("Error tracking sideload progress: {e}"); - tracing::debug!("{e:?}"); } } + .await + { + tracing::error!("Error tracking sideload progress: {e}"); + tracing::debug!("{e:?}"); + } }, Duration::from_secs(600), ), @@ -255,9 +260,9 @@ pub async fn sideload( } .await { - let _ = err_send.send(e.clone_output()); tracing::error!("Error sideloading package: {e}"); tracing::debug!("{e:?}"); + let _ = err_send.send(e); } }); Ok(SideloadResponse { upload, progress }) diff --git a/core/startos/src/logs.rs b/core/startos/src/logs.rs index 1cb3327b6..be5e9cb8f 100644 --- a/core/startos/src/logs.rs +++ b/core/startos/src/logs.rs @@ -30,6 +30,7 @@ use crate::error::ResultExt; use crate::lxc::ContainerId; use crate::prelude::*; use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations}; +use crate::util::net::WebSocketExt; use crate::util::serde::Reversible; use crate::util::Invoke; @@ -80,34 +81,28 @@ async fn ws_handler( .with_kind(ErrorKind::Network)?; } - let mut ws_closed = false; - while let Some(entry) = tokio::select! { - a = logs.try_next() => Some(a?), - a = stream.try_next() => { a.with_kind(crate::ErrorKind::Network)?; ws_closed = true; None } - } { - if let Some(entry) = entry { - let (_, log_entry) = entry.log_entry()?; - stream - .send(ws::Message::Text( - serde_json::to_string(&log_entry).with_kind(ErrorKind::Serialization)?, - )) - .await - .with_kind(ErrorKind::Network)?; + loop { + tokio::select! { + entry = logs.try_next() => { + if let Some(entry) = entry? { + let (_, log_entry) = entry.log_entry()?; + stream + .send(ws::Message::Text( + serde_json::to_string(&log_entry).with_kind(ErrorKind::Serialization)?, + )) + .await + .with_kind(ErrorKind::Network)?; + } else { + return stream.normal_close("complete").await; + } + }, + msg = stream.try_next() => { + if msg.with_kind(crate::ErrorKind::Network)?.is_none() { + return Ok(()) + } + } } } - - if !ws_closed { - stream - .send(ws::Message::Close(Some(ws::CloseFrame { - code: ws::close_code::NORMAL, - reason: "Log Stream Finished".into(), - }))) - .await - .with_kind(ErrorKind::Network)?; - drop(stream); - } - - Ok(()) } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] diff --git a/core/startos/src/net/forward.rs b/core/startos/src/net/forward.rs index ba62945a0..6f3abee15 100644 --- a/core/startos/src/net/forward.rs +++ b/core/startos/src/net/forward.rs @@ -8,10 +8,11 @@ use id_pool::IdPool; use imbl_value::InternedString; use serde::{Deserialize, Serialize}; use tokio::process::Command; -use tokio::sync::{mpsc, watch}; +use tokio::sync::mpsc; use crate::db::model::public::NetworkInterfaceInfo; use crate::prelude::*; +use crate::util::sync::Watch; use crate::util::Invoke; pub const START9_BRIDGE_IFACE: &str = "lxcbr0"; @@ -147,17 +148,16 @@ pub struct LanPortForwardController { _thread: NonDetachingJoinHandle<()>, } impl LanPortForwardController { - pub fn new( - mut net_iface: watch::Receiver>, - ) -> Self { + pub fn new(mut ip_info: Watch>) -> Self { let (req_send, mut req_recv) = mpsc::unbounded_channel(); let thread = NonDetachingJoinHandle::from(tokio::spawn(async move { let mut state = ForwardState::default(); - let mut interfaces = net_iface - .borrow_and_update() - .iter() - .map(|(iface, info)| (iface.clone(), info.public())) - .collect(); + let mut interfaces = ip_info.peek_and_mark_seen(|ip_info| { + ip_info + .iter() + .map(|(iface, info)| (iface.clone(), info.public())) + .collect() + }); let mut reply: Option>> = None; loop { tokio::select! { @@ -171,12 +171,13 @@ impl LanPortForwardController { break; } } - _ = net_iface.changed() => { - interfaces = net_iface - .borrow() - .iter() - .map(|(iface, info)| (iface.clone(), info.public())) - .collect(); + _ = ip_info.changed() => { + interfaces = ip_info.peek(|ip_info| { + ip_info + .iter() + .map(|(iface, info)| (iface.clone(), info.public())) + .collect() + }); } } let res = state.sync(&interfaces).await; diff --git a/core/startos/src/net/network_interface.rs b/core/startos/src/net/network_interface.rs index 991765c86..4f7696c97 100644 --- a/core/startos/src/net/network_interface.rs +++ b/core/startos/src/net/network_interface.rs @@ -1,7 +1,5 @@ use std::collections::{BTreeMap, BTreeSet}; -use std::future::Future; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV6}; -use std::pin::Pin; use std::sync::{Arc, Weak}; use std::task::Poll; use std::time::Duration; @@ -19,7 +17,6 @@ use serde::{Deserialize, Serialize}; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::net::{TcpListener, TcpStream}; use tokio::process::Command; -use tokio::sync::watch; use ts_rs::TS; use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream}; use zbus::zvariant::{ @@ -35,7 +32,7 @@ use crate::prelude::*; use crate::util::future::Until; use crate::util::io::open_file; use crate::util::serde::{display_serializable, HandlerExtSerde}; -use crate::util::sync::SyncMutex; +use crate::util::sync::{SyncMutex, Watch}; use crate::util::Invoke; pub fn network_interface_api() -> ParentHandler { @@ -112,7 +109,7 @@ pub fn network_interface_api() -> ParentHandler { async fn list_interfaces( ctx: RpcContext, ) -> Result, Error> { - Ok(ctx.net_controller.net_iface.ip_info.borrow().clone()) + Ok(ctx.net_controller.net_iface.ip_info.read()) } #[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] @@ -322,7 +319,7 @@ impl<'a> StubStream<'a> for SignalStream<'a> { } #[instrument(skip_all)] -async fn watcher(write_to: watch::Sender>) { +async fn watcher(write_to: Watch>) { loop { let res: Result<(), Error> = async { let connection = Connection::system().await?; @@ -425,7 +422,7 @@ async fn watch_ip( connection: &Connection, device_proxy: device::DeviceProxy<'_>, iface: InternedString, - write_to: &watch::Sender>, + write_to: &Watch>, ) -> Result<(), Error> { let mut until = Until::new() .with_stream( @@ -593,13 +590,13 @@ async fn watch_ip( pub struct NetworkInterfaceController { db: TypedPatchDb, - ip_info: watch::Sender>, + ip_info: Watch>, _watcher: NonDetachingJoinHandle<()>, listeners: SyncMutex>>, } impl NetworkInterfaceController { - pub fn subscribe(&self) -> watch::Receiver> { - self.ip_info.subscribe() + pub fn subscribe(&self) -> Watch> { + self.ip_info.clone_unseen() } async fn sync( @@ -667,7 +664,7 @@ impl NetworkInterfaceController { Ok(()) } pub fn new(db: TypedPatchDb) -> Self { - let (ip_info, mut recv) = watch::channel(BTreeMap::new()); + let mut ip_info = Watch::new(BTreeMap::new()); Self { db: db.clone(), ip_info: ip_info.clone(), @@ -695,7 +692,7 @@ impl NetworkInterfaceController { let res: Result<(), Error> = async { loop { if let Err(e) = async { - let ip_info = { recv.borrow().clone() }; + let ip_info = ip_info.read(); Self::sync(&db, &ip_info).boxed().await?; Ok::<_, Error>(()) @@ -706,7 +703,7 @@ impl NetworkInterfaceController { tracing::debug!("{e:?}"); } - let _ = recv.changed().await; + let _ = ip_info.changed().await; } } .await; @@ -733,12 +730,10 @@ impl NetworkInterfaceController { l.insert(port, Arc::downgrade(&arc)); Ok(()) })?; - let mut ip_info = self.ip_info.subscribe(); - ip_info.mark_changed(); + let ip_info = self.ip_info.clone_unseen(); Ok(NetworkInterfaceListener { _arc: arc, ip_info, - changed: None, listeners: ListenerMap::new(port), }) } @@ -760,12 +755,11 @@ impl NetworkInterfaceController { l.insert(port, Arc::downgrade(&arc)); Ok(()) })?; - let mut ip_info = self.ip_info.subscribe(); + let ip_info = self.ip_info.clone_unseen(); ip_info.mark_changed(); Ok(NetworkInterfaceListener { _arc: arc, ip_info, - changed: None, listeners, }) } @@ -985,9 +979,8 @@ impl ListenerMap { } pub struct NetworkInterfaceListener { - ip_info: watch::Receiver>, + ip_info: Watch>, listeners: ListenerMap, - changed: Option + Send + Sync + 'static>>>, _arc: Arc<()>, } impl NetworkInterfaceListener { @@ -995,29 +988,14 @@ impl NetworkInterfaceListener { self.listeners.port } - fn poll_ip_info_changed(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> { - let mut changed = if let Some(changed) = self.changed.take() { - changed - } else { - let mut ip_info = self.ip_info.clone(); - Box::pin(async move { - let _ = ip_info.changed().await; - }) - }; - let res = changed.poll_unpin(cx); - if res.is_pending() { - self.changed = Some(changed); - } - res - } - pub fn poll_accept( &mut self, cx: &mut std::task::Context<'_>, public: bool, ) -> Poll> { - if self.poll_ip_info_changed(cx).is_ready() || public != self.listeners.prev_public { - self.listeners.update(&*self.ip_info.borrow(), public)?; + while self.ip_info.poll_changed(cx).is_ready() || public != self.listeners.prev_public { + self.ip_info + .peek(|ip_info| self.listeners.update(ip_info, public))?; } self.listeners.poll_accept(cx) } diff --git a/core/startos/src/net/web_server.rs b/core/startos/src/net/web_server.rs index b38a7ee56..468b5d5db 100644 --- a/core/startos/src/net/web_server.rs +++ b/core/startos/src/net/web_server.rs @@ -7,13 +7,12 @@ use std::task::Poll; use std::time::Duration; use axum::Router; -use futures::future::{BoxFuture, Either}; +use futures::future::Either; use futures::FutureExt; use helpers::NonDetachingJoinHandle; use hyper_util::rt::{TokioIo, TokioTimer}; -use hyper_util::service::TowerToHyperService; use tokio::net::{TcpListener, TcpStream}; -use tokio::sync::{oneshot, watch}; +use tokio::sync::oneshot; use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext}; use crate::net::network_interface::NetworkInterfaceListener; @@ -23,6 +22,7 @@ use crate::net::static_server::{ }; use crate::prelude::*; use crate::util::actor::background::BackgroundJobQueue; +use crate::util::sync::Watch; pub struct Accepted { pub https_redirect: bool, @@ -76,42 +76,22 @@ impl Accept for Option
{ #[pin_project::pin_project] pub struct Acceptor { - acceptor: (watch::Sender, watch::Receiver), - changed: Option>, + acceptor: Watch, } impl Acceptor { pub fn new(acceptor: A) -> Self { Self { - acceptor: watch::channel(acceptor), - changed: None, + acceptor: Watch::new(acceptor), } } fn poll_changed(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> { - let mut changed = if let Some(changed) = self.changed.take() { - changed - } else { - let mut recv = self.acceptor.1.clone(); - async move { - let _ = recv.changed().await; - } - .boxed() - }; - let res = changed.poll_unpin(cx); - if res.is_pending() { - self.changed = Some(changed); - } - res + self.acceptor.poll_changed(cx) } fn poll_accept(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { let _ = self.poll_changed(cx); - let mut res = Poll::Pending; - self.acceptor.0.send_if_modified(|a| { - res = a.poll_accept(cx); - false - }); - res + self.acceptor.peek_mut(|a| a.poll_accept(cx)) } async fn accept(&mut self) -> Result { @@ -139,7 +119,7 @@ impl Acceptor { } pub struct WebServerAcceptorSetter { - acceptor: watch::Sender, + acceptor: Watch, } impl WebServerAcceptorSetter>> { pub fn try_upgrade Result>(&self, f: F) -> Result<(), Error> { @@ -160,7 +140,7 @@ impl WebServerAcceptorSetter>> { } } impl Deref for WebServerAcceptorSetter { - type Target = watch::Sender; + type Target = Watch; fn deref(&self) -> &Self::Target { &self.acceptor } @@ -168,8 +148,8 @@ impl Deref for WebServerAcceptorSetter { pub struct WebServer { shutdown: oneshot::Sender<()>, - router: watch::Sender>, - acceptor: watch::Sender, + router: Watch>, + acceptor: Watch, thread: NonDetachingJoinHandle<()>, } impl WebServer { @@ -180,8 +160,9 @@ impl WebServer { } pub fn new(mut acceptor: Acceptor) -> Self { - let acceptor_send = acceptor.acceptor.0.clone(); - let (router, service) = watch::channel::>(None); + let acceptor_send = acceptor.acceptor.clone(); + let router = Watch::>::new(None); + let service = router.clone_unseen(); let (shutdown, shutdown_recv) = oneshot::channel(); let thread = NonDetachingJoinHandle::from(tokio::spawn(async move { #[derive(Clone)] @@ -201,6 +182,34 @@ impl WebServer { } } + struct SwappableRouter(Watch>, bool); + impl hyper::service::Service> for SwappableRouter { + type Response = , + >>::Response; + type Error = , + >>::Error; + type Future = , + >>::Future; + + fn call(&self, req: hyper::Request) -> Self::Future { + use tower_service::Service; + + if self.1 { + redirecter().call(req) + } else { + let router = self.0.read(); + if let Some(mut router) = router { + router.call(req) + } else { + refresher().call(req) + } + } + } + } + let accept = AtomicBool::new(true); let queue_cell = Arc::new(RwLock::new(None)); let graceful = hyper_util::server::graceful::GracefulShutdown::new(); @@ -224,45 +233,16 @@ impl WebServer { loop { if let Err(e) = async { let accepted = acceptor.accept().await?; - if accepted.https_redirect { - queue.add_job( - graceful.watch( - server - .serve_connection_with_upgrades( - TokioIo::new(accepted.stream), - TowerToHyperService::new(redirecter().into_service()), - ) - .into_owned(), - ), - ); - } else { - let service = { service.borrow().clone() }; - if let Some(service) = service { - queue.add_job( - graceful.watch( - server - .serve_connection_with_upgrades( - TokioIo::new(accepted.stream), - TowerToHyperService::new(service.into_service()), - ) - .into_owned(), - ), - ); - } else { - queue.add_job( - graceful.watch( - server - .serve_connection_with_upgrades( - TokioIo::new(accepted.stream), - TowerToHyperService::new( - refresher().into_service(), - ), - ) - .into_owned(), - ), - ); - } - } + queue.add_job( + graceful.watch( + server + .serve_connection_with_upgrades( + TokioIo::new(accepted.stream), + SwappableRouter(service.clone(), accepted.https_redirect), + ) + .into_owned(), + ), + ); Ok::<_, Error>(()) } @@ -303,7 +283,7 @@ impl WebServer { } pub fn serve_router(&mut self, router: Router) { - self.router.send_replace(Some(router)); + self.router.send(Some(router)) } pub fn serve_main(&mut self, ctx: RpcContext) { diff --git a/core/startos/src/service/service_actor.rs b/core/startos/src/service/service_actor.rs index b88136650..bb30d2a98 100644 --- a/core/startos/src/service/service_actor.rs +++ b/core/startos/src/service/service_actor.rs @@ -66,9 +66,7 @@ impl Actor for ServiceActor { tracing::debug!("{e:?}"); } - if ip_info.changed().await.is_err() { - break; - }; + ip_info.changed().await; } }); } diff --git a/core/startos/src/update/mod.rs b/core/startos/src/update/mod.rs index d88838d4a..7daa4f3b2 100644 --- a/core/startos/src/update/mod.rs +++ b/core/startos/src/update/mod.rs @@ -20,7 +20,7 @@ use ts_rs::TS; use crate::context::{CliContext, RpcContext}; use crate::disk::mount::filesystem::bind::Bind; use crate::disk::mount::filesystem::block_dev::BlockDev; -use crate::disk::mount::filesystem::efivarfs::{ EfiVarFs}; +use crate::disk::mount::filesystem::efivarfs::EfiVarFs; use crate::disk::mount::filesystem::overlayfs::OverlayGuard; use crate::disk::mount::filesystem::MountType; use crate::disk::mount::guard::{GenericMountGuard, MountGuard, TmpMountGuard}; @@ -106,7 +106,7 @@ pub async fn update_system( .with_kind(ErrorKind::Database)?, ) .await; - while { + loop { let progress = ctx .db .peek() @@ -122,14 +122,22 @@ pub async fn update_system( )) .await .with_kind(ErrorKind::Network)?; - progress.is_some() - } { - sub.recv().await; + if progress.is_none() { + return ws.normal_close("complete").await; + } + tokio::select! { + _ = sub.recv() => (), + res = async { + loop { + if ws.recv().await.transpose().with_kind(ErrorKind::Network)?.is_none() { + return Ok(()) + } + } + } => { + return res + } + } } - - ws.normal_close("complete").await?; - - Ok::<_, Error>(()) } .await { diff --git a/core/startos/src/util/net.rs b/core/startos/src/util/net.rs index 9e1beeaba..1189f70f2 100644 --- a/core/startos/src/util/net.rs +++ b/core/startos/src/util/net.rs @@ -19,13 +19,8 @@ pub trait WebSocketExt { } impl WebSocketExt for ws::WebSocket { - async fn normal_close(mut self, msg: impl Into> + Send) -> Result<(), Error> { - self.send(ws::Message::Close(Some(CloseFrame { - code: 1000, - reason: msg.into(), - }))) - .await - .with_kind(ErrorKind::Network) + async fn normal_close(self, msg: impl Into> + Send) -> Result<(), Error> { + self.close_result(Ok::<_, Error>(msg)).await } async fn close_result( mut self, @@ -38,15 +33,23 @@ impl WebSocketExt for ws::WebSocket { reason: msg.into(), }))) .await - .with_kind(ErrorKind::Network), + .with_kind(ErrorKind::Network)?, Err(e) => self .send(ws::Message::Close(Some(CloseFrame { code: 1011, reason: e.to_string().into(), }))) .await - .with_kind(ErrorKind::Network), + .with_kind(ErrorKind::Network)?, } + while !matches!( + self.recv() + .await + .transpose() + .with_kind(ErrorKind::Network)?, + Some(ws::Message::Close(_)) | None + ) {} + Ok(()) } } diff --git a/core/startos/src/util/sync.rs b/core/startos/src/util/sync.rs index 2630858a9..ca7b4c6bb 100644 --- a/core/startos/src/util/sync.rs +++ b/core/startos/src/util/sync.rs @@ -1,3 +1,7 @@ +use std::pin::Pin; +use std::sync::Arc; +use std::task::{Poll, Waker}; + #[derive(Debug, Default)] pub struct SyncMutex(std::sync::Mutex); impl SyncMutex { @@ -11,3 +15,140 @@ impl SyncMutex { f(&*self.0.lock().unwrap()) } } + +struct WatchShared { + version: u64, + data: T, + wakers: Vec, +} +impl WatchShared { + fn modified(&mut self) { + self.version += 1; + for waker in self.wakers.drain(..) { + waker.wake(); + } + } +} + +#[pin_project::pin_project] +pub struct Watch { + shared: Arc>>, + version: u64, +} +impl Clone for Watch { + fn clone(&self) -> Self { + Self { + shared: self.shared.clone(), + version: self.version, + } + } +} +impl Watch { + pub fn new(init: T) -> Self { + Self { + shared: Arc::new(SyncMutex::new(WatchShared { + version: 1, + data: init, + wakers: Vec::new(), + })), + version: 0, + } + } + pub fn clone_unseen(&self) -> Self { + Self { + shared: self.shared.clone(), + version: 0, + } + } + pub fn poll_changed(&mut self, cx: &mut std::task::Context<'_>) -> Poll<()> { + self.shared.mutate(|shared| { + if shared.version != self.version { + self.version = shared.version; + Poll::Ready(()) + } else { + let waker = cx.waker(); + if !shared.wakers.iter().any(|w| w.will_wake(waker)) { + shared.wakers.push(waker.clone()); + } + Poll::Pending + } + }) + } + pub async fn changed(&mut self) { + futures::future::poll_fn(|cx| self.poll_changed(cx)).await + } + pub fn send_if_modified bool>(&self, modify: F) -> bool { + self.shared.mutate(|shared| { + let changed = modify(&mut shared.data); + if changed { + shared.modified(); + } + changed + }) + } + pub fn send_modify U>(&self, modify: F) -> U { + self.shared.mutate(|shared| { + let res = modify(&mut shared.data); + shared.modified(); + res + }) + } + pub fn send_replace(&self, new: T) -> T { + self.send_modify(|a| std::mem::replace(a, new)) + } + pub fn send(&self, new: T) { + self.send_replace(new); + } + pub fn mark_changed(&self) { + self.shared.mutate(|shared| shared.modified()) + } + pub fn mark_unseen(&mut self) { + self.version = 0; + } + pub fn mark_seen(&mut self) { + self.shared.peek(|shared| { + self.version = shared.version; + }) + } + pub fn peek U>(&self, f: F) -> U { + self.shared.peek(|shared| f(&shared.data)) + } + pub fn peek_and_mark_seen U>(&mut self, f: F) -> U { + self.shared.peek(|shared| { + self.version = shared.version; + f(&shared.data) + }) + } + pub fn peek_mut U>(&self, f: F) -> U { + self.shared.mutate(|shared| f(&mut shared.data)) + } +} +impl Watch { + pub fn read(&self) -> T { + self.peek(|a| a.clone()) + } +} +impl futures::Stream for Watch { + type Item = T; + fn poll_next( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let this = self.project(); + this.shared.mutate(|shared| { + if shared.version != *this.version { + *this.version = shared.version; + Poll::Ready(Some(shared.data.clone())) + } else { + let waker = cx.waker(); + if !shared.wakers.iter().any(|w| w.will_wake(waker)) { + shared.wakers.push(waker.clone()); + } + Poll::Pending + } + }) + } + fn size_hint(&self) -> (usize, Option) { + (1, None) + } +} diff --git a/core/startos/src/version/update_details/v0_3_6.md b/core/startos/src/version/update_details/v0_3_6.md index b93e8ad1a..177845f08 100644 --- a/core/startos/src/version/update_details/v0_3_6.md +++ b/core/startos/src/version/update_details/v0_3_6.md @@ -17,17 +17,16 @@ StartOS v0.3.6 is a complete rewrite of the OS internals (everything you don't s ## Changelog - [Switch to lxc-based container runtime](#lxc) -- [Update s9pk archive format](#new-s9pk-archive-format) -- [Improve config](#better-config) -- [Unify Actions](#unify-actions) +- [Update s9pk archive format](#s9pk-archive-format) +- [Improve Actions](#actions) - [Use squashfs images for OS updates](#squashfs-updates) -- [Introduce Typescript package API and SDK](#typescript-package-api-and-sdk) +- [Introduce Typescript package API and SDK](#typescript-sdk) - [Remove Postgresql](#remove-postgressql) - [Implement detailed progress reporting](#progress-reporting) - [Improve registry protocol](#registry-protocol) - [Replace unique .local URLs with unique ports](#lan-port-forwarding) - [Use start-fs Fuse module for improved backups](#improved-backups) -- [Switch to Exver for versioning](#Exver) +- [Switch to Exver for versioning](#exver) - [Support clearnet hosting via start-cli](#clearnet) ### LXC @@ -38,21 +37,17 @@ StartOS now uses a nested container paradigm based on LXC for the outer containe The S9PK archive format has been overhauled to allow for signature verification of partial downloads, and allow direct mounting of container images without unpacking the s9pk. -### Better config - -Expanded support for input types and a new UI makes configuring services easier and more powerful. - ### Actions -Actions take arbitrary form input _and_ return arbitrary responses, thus satisfying the needs of both Config and Properties, which will be removed in a future release. This gives packages developers the ability to break up Config and Properties into smaller, more specific formats, or to exclude them entirely without polluting the UI. +Actions take arbitrary form input and return arbitrary responses, thus satisfying the needs of both Config and Properties, which have been removed. The new actions API gives packages developers the ability to break up Config and Properties into smaller, more specific formats, or to exclude them entirely without polluting the UI. Improved form design and new input types round out the actions experience. ### Squashfs updates StartOS now uses squashfs images to represent OS updates. This allows for better update verification, and improved reliability over rsync updates. -### Typescript package API and SDK +### Typescript SDK -StartOS now exposes a Typescript API. Package developers can take advantage in a simple, typesafe way using the new start-sdk. A barebones StartOS package (s9pk) can be produced in minutes with minimal knowledge or skill. More advanced developers can use the SDK to create highly customized user experiences with their service. +Package developers can now take advantage of StartOS APIs using the new start-sdk, available in Typescript. A barebones StartOS package (s9pk) can be produced in minutes with minimal knowledge or skill. More advanced developers can use the SDK to create highly customized user experiences with their service. ### Remove PostgresSQL @@ -76,8 +71,14 @@ The new start-fs fuse module unifies file system expectations for various platfo ### Exver -StartOS now uses Extended Versioning (Exver), which consists of three parts, separated by semicolons: (1) a Semver-compliant upstream version, (2) a Semver-compliant wrapper version, and (3) an optional "flavor" prefix. Flavors can be thought of as alternative implementations of services, where a user would only want one or the other installed, and data can feasibly be migrating beetween the two. Another common characteristic of flavors is that they satisfy the same API requirement of dependents, though this is not strictly necessary. A valid Exver looks something like this: `#knots:28.0.:1.0-beta.1`. This would translate to "the first beta release of StartOS wrapper version 1.0 of Bitcoin Knots version 27.0". +StartOS now uses Extended Versioning (Exver), which consists of three parts: (1) a Semver-compliant upstream version, (2) a Semver-compliant wrapper version, and (3) an optional "flavor" prefix. Flavors can be thought of as alternative implementations of services, where a user would only want one or the other installed, and data can feasibly be migrating between the two. Another common characteristic of flavors is that they satisfy the same API requirement of dependents, though this is not strictly necessary. A valid Exver looks something like this: `#knots:28.0.:1.0-beta.1`. This would translate to "the first beta release of StartOS wrapper version 1.0 of Bitcoin Knots version 27.0". ### Clearnet -It is now possible, and quite easy, to expose specific services interfaces to the public Internet on a standard domain using start-cli. This functionality will be expanded upon and moved into the StartOS UI in a future release. +It is now possible, and quite easy, to expose service interfaces to the public Internet on a standard domain using start-cli. In addition to choosing which service interfaces to expose on which domains/subdomains, users have two options: + +1. Open ports on their router. This option is free and easy to accomplish with most routers. The drawback is that the user's home IP address is revealed to anyone accessing the exposes resources. For example, hosting a blog in this way would reveal your home IP address, and therefor your approximate location on Earth, to your readers. + +2. Use a Wireguard VPN to proxy web traffic. This option requires the user to provision a $5-$10/month remote VPS and perform a few, simple commands. The result is the successful obfuscation of the users home IP address. + +The CLI-driven clearnet functionality will be expanded upon and moved into the main StartOS UI in a future release. diff --git a/web/projects/ui/src/app/app-routing.module.ts b/web/projects/ui/src/app/app-routing.module.ts index e7a2036ec..e16085a97 100644 --- a/web/projects/ui/src/app/app-routing.module.ts +++ b/web/projects/ui/src/app/app-routing.module.ts @@ -12,7 +12,7 @@ const routes: Routes = [ }, { path: 'login', - canActivate: [UnauthGuard], + canActivate: [UnauthGuard, stateNot(['error', 'initializing'])], loadChildren: () => import('./pages/login/login.module').then(m => m.LoginPageModule), }, diff --git a/web/projects/ui/src/app/pages/init/init.service.ts b/web/projects/ui/src/app/pages/init/init.service.ts index c58e7777e..9fbcc933d 100644 --- a/web/projects/ui/src/app/pages/init/init.service.ts +++ b/web/projects/ui/src/app/pages/init/init.service.ts @@ -1,10 +1,8 @@ import { inject, Injectable } from '@angular/core' -import { ErrorService } from '@start9labs/shared' import { T } from '@start9labs/start-sdk' import { catchError, defer, - EMPTY, from, map, Observable, @@ -24,40 +22,46 @@ interface MappedProgress { export class InitService extends Observable { private readonly state = inject(StateService) private readonly api = inject(ApiService) - private readonly errorService = inject(ErrorService) private readonly progress$ = defer(() => from(this.api.initGetProgress()), ).pipe( switchMap(({ guid, progress }) => - this.api.openWebsocket$(guid).pipe(startWith(progress)), + this.api + .openWebsocket$(guid, { + closeObserver: { + next: () => { + this.state.syncState() + }, + }, + }) + .pipe(startWith(progress)), ), - map(({ phases, overall }) => { - return { - total: getOverallDecimal(overall), - message: phases - .filter( - ( - p, - ): p is { - name: string - progress: { - done: number - total: number | null - } - } => p.progress !== true && p.progress !== null, - ) - .map(p => `${p.name}${getPhaseBytes(p.progress)}`) - .join(', '), - } - }), + map(({ phases, overall }) => ({ + total: getOverallDecimal(overall), + message: phases + .filter( + ( + p, + ): p is { + name: string + progress: { + done: number + total: number | null + } + } => p.progress !== true && p.progress !== null, + ) + .map(p => `${p.name}${getPhaseBytes(p.progress)}`) + .join(', '), + })), tap(({ total }) => { if (total === 1) { this.state.syncState() } }), - catchError(e => { + catchError((e, caught$) => { console.error(e) - return EMPTY + this.state.syncState() + return caught$ }), ) diff --git a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.html b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.html index bdfe8e3ed..6178ebccc 100644 --- a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.html +++ b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.html @@ -35,19 +35,17 @@ > Downgrade - - - Reinstall - - + + Reinstall + - + console.error(e)) - await firstValueFrom(this.progress$.pipe(filter(Boolean))) + await this.api.uploadPackage(res.upload, this.toUpload.file!) + await firstValueFrom(this.progress$) } catch (e: any) { this.errorService.handleError(e) } finally { diff --git a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts index d157272ff..df6ec0868 100644 --- a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts +++ b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.service.ts @@ -1,6 +1,16 @@ -import { Injectable } from '@angular/core' +import { inject, Injectable } from '@angular/core' +import { Router } from '@angular/router' +import { ErrorService } from '@start9labs/shared' import { T } from '@start9labs/start-sdk' -import { BehaviorSubject, endWith, shareReplay, Subject, switchMap } from 'rxjs' +import { + catchError, + EMPTY, + endWith, + shareReplay, + Subject, + switchMap, + tap, +} from 'rxjs' import { ApiService } from 'src/app/services/api/embassy-api.service' @Injectable({ @@ -8,11 +18,34 @@ import { ApiService } from 'src/app/services/api/embassy-api.service' }) export class SideloadService { private readonly guid$ = new Subject() + private readonly errorService = inject(ErrorService) + private readonly router = inject(Router) readonly progress$ = this.guid$.pipe( switchMap(guid => - this.api.openWebsocket$(guid).pipe(endWith(null)), + this.api + .openWebsocket$(guid, { + closeObserver: { + next: event => { + if (event.code !== 1000) { + this.errorService.handleError(event.reason) + } + }, + }, + }) + .pipe( + tap(p => { + if (p.overall === true) { + this.router.navigate([''], { replaceUrl: true }) + } + }), + endWith(null), + ), ), + catchError(e => { + this.errorService.handleError('Websocket connection broken. Try again.') + return EMPTY + }), shareReplay(1), ) diff --git a/web/projects/ui/src/app/services/api/embassy-api.service.ts b/web/projects/ui/src/app/services/api/embassy-api.service.ts index 280ac79f3..551011533 100644 --- a/web/projects/ui/src/app/services/api/embassy-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-api.service.ts @@ -7,6 +7,7 @@ import { GetPackagesRes, MarketplacePkg, } from '@start9labs/marketplace' +import { WebSocketSubject } from 'rxjs/webSocket' export abstract class ApiService { // http @@ -30,7 +31,7 @@ export abstract class ApiService { abstract openWebsocket$( guid: string, config?: RR.WebsocketConfig, - ): Observable + ): WebSocketSubject // state diff --git a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts index 6241eaad7..9893585a4 100644 --- a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts @@ -11,7 +11,7 @@ import { PATCH_CACHE } from 'src/app/services/patch-db/patch-db-source' import { ApiService } from './embassy-api.service' import { RR } from './api.types' import { ConfigService } from '../config.service' -import { webSocket } from 'rxjs/webSocket' +import { webSocket, WebSocketSubject } from 'rxjs/webSocket' import { Observable, filter, firstValueFrom } from 'rxjs' import { AuthService } from '../auth.service' import { DOCUMENT } from '@angular/common' @@ -85,7 +85,7 @@ export class LiveApiService extends ApiService { openWebsocket$( guid: string, config: RR.WebsocketConfig = {}, - ): Observable { + ): WebSocketSubject { const { location } = this.document.defaultView! const protocol = location.protocol === 'http:' ? 'ws' : 'wss' const host = location.host diff --git a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 93925cc73..23296ad15 100644 --- a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -37,6 +37,7 @@ import { GetPackagesRes, MarketplacePkg, } from '@start9labs/marketplace' +import { WebSocketSubject } from 'rxjs/webSocket' const PROGRESS: T.FullProgress = { overall: { @@ -107,11 +108,11 @@ export class MockApiService extends ApiService { openWebsocket$( guid: string, config: RR.WebsocketConfig = {}, - ): Observable { + ): WebSocketSubject { if (guid === 'db-guid') { return this.mockWsSource$.pipe( shareReplay({ bufferSize: 1, refCount: true }), - ) + ) as WebSocketSubject } else if (guid === 'logs-guid') { return interval(50).pipe( map((_, index) => { @@ -120,16 +121,16 @@ export class MockApiService extends ApiService { if (index === 100) throw new Error('HAAHHA') return Mock.ServerLogs[0] }), - ) + ) as WebSocketSubject } else if (guid === 'init-progress-guid') { return from(this.initProgress()).pipe( startWith(PROGRESS), - ) as Observable + ) as WebSocketSubject } else if (guid === 'sideload-progress-guid') { config.openObserver?.next(new Event('')) return from(this.initProgress()).pipe( startWith(PROGRESS), - ) as Observable + ) as WebSocketSubject } else { throw new Error('invalid guid type') } diff --git a/web/projects/ui/src/app/services/auth.service.ts b/web/projects/ui/src/app/services/auth.service.ts index 9c16d0e26..2db008d8e 100644 --- a/web/projects/ui/src/app/services/auth.service.ts +++ b/web/projects/ui/src/app/services/auth.service.ts @@ -27,9 +27,9 @@ export class AuthService { ) {} init(): void { - const loggedIn = this.storage.get(this.LOGGED_IN_KEY) + const loggedIn = this.storage.get(this.LOGGED_IN_KEY) if (loggedIn) { - this.setVerified() + this.authState$.next(AuthState.VERIFIED) } else { this.setUnverified() } From e012a29b5e376d2bc7a58a8bb4e47a54acbb828c Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 14 Jan 2025 17:32:19 -0700 Subject: [PATCH 09/35] add smtp to frontend (#2802) * add smtp to frontend * left align headers * just email * change all to email * fix test-smtp api * types * fix email from and login address handling --------- Co-authored-by: Aiden McClelland --- core/startos/src/bins/registry.rs | 2 +- core/startos/src/lib.rs | 4 +- core/startos/src/system.rs | 52 ++++++++++-- core/startos/src/version/mod.rs | 2 +- .../lib/actions/input/inputSpecConstants.ts | 4 +- sdk/base/lib/osBindings/TestSmtpParams.ts | 10 +++ sdk/base/lib/osBindings/index.ts | 1 + sdk/base/lib/util/patterns.ts | 5 ++ sdk/base/lib/util/regexes.ts | 8 +- web/package-lock.json | 28 ++++++- .../pages/server-routes/email/email.module.ts | 42 ++++++++++ .../pages/server-routes/email/email.page.html | 70 ++++++++++++++++ .../pages/server-routes/email/email.page.scss | 9 ++ .../pages/server-routes/email/email.page.ts | 83 +++++++++++++++++++ .../server-routes/server-routing.module.ts | 7 +- .../server-show/server-show.page.ts | 13 ++- .../pages/server-routes/wifi/wifi.page.html | 2 +- .../ui/src/app/services/api/api.types.ts | 11 +++ .../app/services/api/embassy-api.service.ts | 8 ++ .../services/api/embassy-live-api.service.ts | 14 ++++ .../services/api/embassy-mock-api.service.ts | 35 ++++++++ 21 files changed, 389 insertions(+), 21 deletions(-) create mode 100644 sdk/base/lib/osBindings/TestSmtpParams.ts create mode 100644 web/projects/ui/src/app/pages/server-routes/email/email.module.ts create mode 100644 web/projects/ui/src/app/pages/server-routes/email/email.page.html create mode 100644 web/projects/ui/src/app/pages/server-routes/email/email.page.scss create mode 100644 web/projects/ui/src/app/pages/server-routes/email/email.page.ts diff --git a/core/startos/src/bins/registry.rs b/core/startos/src/bins/registry.rs index 9c2cd2b92..a71b737af 100644 --- a/core/startos/src/bins/registry.rs +++ b/core/startos/src/bins/registry.rs @@ -1,7 +1,7 @@ use std::ffi::OsString; use clap::Parser; -use futures::{FutureExt}; +use futures::FutureExt; use tokio::signal::unix::signal; use tracing::instrument; diff --git a/core/startos/src/lib.rs b/core/startos/src/lib.rs index 6ab0529c2..ad214da34 100644 --- a/core/startos/src/lib.rs +++ b/core/startos/src/lib.rs @@ -302,9 +302,9 @@ pub fn server() -> ParentHandler { ) .subcommand( "test-smtp", - from_fn_async(system::test_system_smtp) + from_fn_async(system::test_smtp) .no_display() - .with_about("Send test email using system smtp server and credentials") + .with_about("Send test email using provided smtp server and credentials") .with_call_remote::() ) .subcommand( diff --git a/core/startos/src/system.rs b/core/startos/src/system.rs index e44431894..123fdec42 100644 --- a/core/startos/src/system.rs +++ b/core/startos/src/system.rs @@ -7,7 +7,7 @@ use clap::Parser; use color_eyre::eyre::eyre; use futures::FutureExt; use imbl::vector; -use mail_send::mail_builder::MessageBuilder; +use mail_send::mail_builder::{self, MessageBuilder}; use mail_send::SmtpClientBuilder; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; use rustls::crypto::CryptoProvider; @@ -878,15 +878,33 @@ pub async fn clear_system_smtp(ctx: RpcContext) -> Result<(), Error> { } Ok(()) } -pub async fn test_system_smtp( +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)] +#[ts(export)] +#[serde(rename_all = "camelCase")] +pub struct TestSmtpParams { + #[arg(long)] + pub server: String, + #[arg(long)] + pub port: u16, + #[arg(long)] + pub from: String, + #[arg(long)] + pub to: String, + #[arg(long)] + pub login: String, + #[arg(long)] + pub password: Option, +} +pub async fn test_smtp( _: RpcContext, - SmtpValue { + TestSmtpParams { server, port, from, + to, login, password, - }: SmtpValue, + }: TestSmtpParams, ) -> Result<(), Error> { use rustls_pki_types::pem::PemObject; @@ -913,17 +931,35 @@ pub async fn test_system_smtp( ); let client = SmtpClientBuilder::new_with_tls_config(server, port, cfg) .implicit_tls(false) - .credentials((login.clone().split_once("@").unwrap().0.to_owned(), pass_val)); + .credentials((login.split("@").next().unwrap().to_owned(), pass_val)); + + fn parse_address<'a>(addr: &'a str) -> mail_builder::headers::address::Address<'a> { + if addr.find("<").map_or(false, |start| { + addr.find(">").map_or(false, |end| start < end) + }) { + addr.split_once("<") + .map(|(name, addr)| (name.trim(), addr.strip_suffix(">").unwrap_or(addr))) + .unwrap() + .into() + } else { + addr.into() + } + } let message = MessageBuilder::new() - .from((from.clone(), login.clone())) - .to(vec![(from, login)]) + .from(parse_address(&from)) + .to(parse_address(&to)) .subject("StartOS Test Email") .text_body("This is a test email sent from your StartOS Server"); client .connect() .await - .map_err(|e| Error::new(eyre!("mail-send connection error: {:?}", e), ErrorKind::Unknown))? + .map_err(|e| { + Error::new( + eyre!("mail-send connection error: {:?}", e), + ErrorKind::Unknown, + ) + })? .send(message) .await .map_err(|e| Error::new(eyre!("mail-send send error: {:?}", e), ErrorKind::Unknown))?; diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index e8d5f2249..ff7c3da99 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -7,7 +7,7 @@ use futures::future::BoxFuture; use futures::{Future, FutureExt}; use imbl::Vector; use imbl_value::{to_value, InternedString}; -use patch_db::json_ptr::{ ROOT}; +use patch_db::json_ptr::ROOT; use crate::context::RpcContext; use crate::prelude::*; diff --git a/sdk/base/lib/actions/input/inputSpecConstants.ts b/sdk/base/lib/actions/input/inputSpecConstants.ts index 57bf8a79b..64857d419 100644 --- a/sdk/base/lib/actions/input/inputSpecConstants.ts +++ b/sdk/base/lib/actions/input/inputSpecConstants.ts @@ -25,9 +25,9 @@ export const customSmtp = InputSpec.of, never>({ name: "From Address", required: true, default: null, - placeholder: "test@example.com", + placeholder: "Example Name ", inputmode: "email", - patterns: [Patterns.email], + patterns: [Patterns.emailWithName], }), login: Value.text({ name: "Login", diff --git a/sdk/base/lib/osBindings/TestSmtpParams.ts b/sdk/base/lib/osBindings/TestSmtpParams.ts new file mode 100644 index 000000000..06b218a34 --- /dev/null +++ b/sdk/base/lib/osBindings/TestSmtpParams.ts @@ -0,0 +1,10 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type TestSmtpParams = { + server: string + port: number + from: string + to: string + login: string + password: string | null +} diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index 6eff86872..c8b49d00a 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -186,6 +186,7 @@ export { SignAssetParams } from "./SignAssetParams" export { SignerInfo } from "./SignerInfo" export { SmtpValue } from "./SmtpValue" export { StartStop } from "./StartStop" +export { TestSmtpParams } from "./TestSmtpParams" export { UnsetPublicParams } from "./UnsetPublicParams" export { UpdatingState } from "./UpdatingState" export { VerifyCifsParams } from "./VerifyCifsParams" diff --git a/sdk/base/lib/util/patterns.ts b/sdk/base/lib/util/patterns.ts index c117c89e5..46f67b6b8 100644 --- a/sdk/base/lib/util/patterns.ts +++ b/sdk/base/lib/util/patterns.ts @@ -52,6 +52,11 @@ export const email: Pattern = { description: "Must be a valid email address", } +export const emailWithName: Pattern = { + regex: regexes.emailWithName.source, + description: "Must be a valid email address, optionally with a name", +} + export const base64: Pattern = { regex: regexes.base64.source, description: diff --git a/sdk/base/lib/util/regexes.ts b/sdk/base/lib/util/regexes.ts index f26196381..e4e11766a 100644 --- a/sdk/base/lib/util/regexes.ts +++ b/sdk/base/lib/util/regexes.ts @@ -26,8 +26,12 @@ export const torUrl = // https://ihateregex.io/expr/ascii/ export const ascii = /^[ -~]*$/ -//https://ihateregex.io/expr/email/ -export const email = /[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+/ +// https://www.regular-expressions.info/email.html +export const email = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/ + +export const emailWithName = new RegExp( + `(${email.source})|([^<]*<(${email.source})>)`, +) //https://rgxdb.com/r/1NUN74O6 export const base64 = diff --git a/web/package-lock.json b/web/package-lock.json index 1c34d8dc8..ee7a93d8d 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -116,7 +116,33 @@ "rxjs": ">=7.0.0" } }, - "../sdk/baseDist": {}, + "../sdk/baseDist": { + "name": "@start9labs/start-sdk-base", + "license": "MIT", + "dependencies": { + "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", + "isomorphic-fetch": "^3.0.0", + "lodash.merge": "^4.6.2", + "mime-types": "^2.1.35", + "ts-matches": "^6.1.0", + "yaml": "^2.2.2" + }, + "devDependencies": { + "@types/jest": "^29.4.0", + "@types/lodash.merge": "^4.6.2", + "@types/mime-types": "^2.1.4", + "jest": "^29.4.3", + "peggy": "^3.0.2", + "prettier": "^3.2.5", + "ts-jest": "^29.0.5", + "ts-node": "^10.9.1", + "ts-pegjs": "^4.2.1", + "tsx": "^4.7.1", + "typescript": "^5.0.4" + } + }, "node_modules/@adobe/css-tools": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", diff --git a/web/projects/ui/src/app/pages/server-routes/email/email.module.ts b/web/projects/ui/src/app/pages/server-routes/email/email.module.ts new file mode 100644 index 000000000..f6b0c735d --- /dev/null +++ b/web/projects/ui/src/app/pages/server-routes/email/email.module.ts @@ -0,0 +1,42 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { Routes, RouterModule } from '@angular/router' +import { TuiInputModule } from '@taiga-ui/kit' +import { + TuiNotificationModule, + TuiTextfieldControllerModule, +} from '@taiga-ui/core' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' +import { EmailPage } from './email.page' +import { FormModule } from 'src/app/components/form/form.module' +import { IonicModule } from '@ionic/angular' +import { TuiErrorModule, TuiModeModule } from '@taiga-ui/core' +import { TuiAppearanceModule, TuiButtonModule } from '@taiga-ui/experimental' + +const routes: Routes = [ + { + path: '', + component: EmailPage, + }, +] + +@NgModule({ + imports: [ + CommonModule, + IonicModule, + RouterModule.forChild(routes), + CommonModule, + FormsModule, + ReactiveFormsModule, + TuiButtonModule, + TuiInputModule, + FormModule, + TuiNotificationModule, + TuiTextfieldControllerModule, + TuiAppearanceModule, + TuiModeModule, + TuiErrorModule, + ], + declarations: [EmailPage], +}) +export class EmailPageModule {} diff --git a/web/projects/ui/src/app/pages/server-routes/email/email.page.html b/web/projects/ui/src/app/pages/server-routes/email/email.page.html new file mode 100644 index 000000000..5e0e58fa4 --- /dev/null +++ b/web/projects/ui/src/app/pages/server-routes/email/email.page.html @@ -0,0 +1,70 @@ + + + Email + + + + + + + + + Fill out the form below to connect to an external SMTP server. With your + permission, installed services can use the SMTP server to send emails. To + grant permission to a particular service, visit that service's "Actions" + page. Not all services support sending emails. + + View instructions + + + +
+

SMTP Credentials

+ + + +
+
+

Send Test Email

+ + To Address + + + +
+
+ diff --git a/web/projects/ui/src/app/pages/server-routes/email/email.page.scss b/web/projects/ui/src/app/pages/server-routes/email/email.page.scss new file mode 100644 index 000000000..b15986fc9 --- /dev/null +++ b/web/projects/ui/src/app/pages/server-routes/email/email.page.scss @@ -0,0 +1,9 @@ +form { + padding-top: 24px; + margin: auto; + max-width: 30rem; +} + +h3 { + display: flex; +} \ No newline at end of file diff --git a/web/projects/ui/src/app/pages/server-routes/email/email.page.ts b/web/projects/ui/src/app/pages/server-routes/email/email.page.ts new file mode 100644 index 000000000..ebe59742e --- /dev/null +++ b/web/projects/ui/src/app/pages/server-routes/email/email.page.ts @@ -0,0 +1,83 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { IST, inputSpec } from '@start9labs/start-sdk' +import { TuiDialogService } from '@taiga-ui/core' +import { PatchDB } from 'patch-db-client' +import { switchMap, tap } from 'rxjs' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { FormService } from 'src/app/services/form.service' +import { DataModel } from 'src/app/services/patch-db/data-model' +import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec' + +@Component({ + selector: 'email-page', + templateUrl: './email.page.html', + styleUrls: ['./email.page.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class EmailPage { + private readonly dialogs = inject(TuiDialogService) + private readonly loader = inject(LoadingService) + private readonly errorService = inject(ErrorService) + private readonly formService = inject(FormService) + private readonly patch = inject>(PatchDB) + private readonly api = inject(ApiService) + + isSaved = false + testAddress = '' + + readonly spec: Promise = configBuilderToSpec( + inputSpec.constants.customSmtp, + ) + readonly form$ = this.patch.watch$('serverInfo', 'smtp').pipe( + tap(value => (this.isSaved = !!value)), + switchMap(async value => + this.formService.createForm(await this.spec, value), + ), + ) + + async save( + value: typeof inputSpec.constants.customSmtp._TYPE | null, + ): Promise { + const loader = this.loader.open('Saving...').subscribe() + + try { + if (value) { + await this.api.setSmtp(value) + this.isSaved = true + } else { + await this.api.clearSmtp({}) + this.isSaved = false + } + } catch (e: any) { + this.errorService.handleError(e) + } finally { + loader.unsubscribe() + } + } + + async sendTestEmail(value: typeof inputSpec.constants.customSmtp._TYPE) { + const loader = this.loader.open('Sending email...').subscribe() + + try { + await this.api.testSmtp({ + to: this.testAddress, + ...value, + }) + } catch (e: any) { + this.errorService.handleError(e) + } finally { + loader.unsubscribe() + } + + this.dialogs + .open( + `A test email has been sent to ${this.testAddress}.

Check your spam folder and mark as not spam`, + { + label: 'Success', + size: 's', + }, + ) + .subscribe() + } +} diff --git a/web/projects/ui/src/app/pages/server-routes/server-routing.module.ts b/web/projects/ui/src/app/pages/server-routes/server-routing.module.ts index 945f1b1c9..004bd53b1 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-routing.module.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-routing.module.ts @@ -76,10 +76,15 @@ const routes: Routes = [ import('./ssh-keys/ssh-keys.module').then(m => m.SSHKeysPageModule), }, { - path: 'wireless', + path: 'wifi', loadChildren: () => import('./wifi/wifi.module').then(m => m.WifiPageModule), }, + { + path: 'email', + loadChildren: () => + import('./email/email.module').then(m => m.EmailPageModule), + }, ] @NgModule({ diff --git a/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts index 3b89deba3..fa3f26702 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts @@ -463,6 +463,15 @@ export class ServerShowPage { detail: true, disabled$: of(false), }, + { + title: 'Email', + description: 'Connect to an external SMTP server for sending emails', + icon: 'mail-outline', + action: () => + this.navCtrl.navigateForward(['email'], { relativeTo: this.route }), + detail: true, + disabled$: of(false), + }, { title: 'SSH', description: @@ -474,12 +483,12 @@ export class ServerShowPage { disabled$: of(false), }, { - title: 'Wireless', + title: 'WiFi', description: 'Connect your server to WiFi instead of Ethernet (not recommended)', icon: 'wifi', action: () => - this.navCtrl.navigateForward(['wireless'], { + this.navCtrl.navigateForward(['wifi'], { relativeTo: this.route, }), detail: true, diff --git a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html index 1ddb44225..ce5ceb56f 100644 --- a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html +++ b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.html @@ -3,7 +3,7 @@ - Wireless Settings + WiFi Settings Refresh diff --git a/web/projects/ui/src/app/services/api/api.types.ts b/web/projects/ui/src/app/services/api/api.types.ts index 9120a2df7..bae63b12a 100644 --- a/web/projects/ui/src/app/services/api/api.types.ts +++ b/web/projects/ui/src/app/services/api/api.types.ts @@ -102,6 +102,17 @@ export module RR { } // net.tor.reset export type ResetTorRes = null + // smtp + + export type SetSMTPReq = T.SmtpValue // server.set-smtp + export type SetSMTPRes = null + + export type ClearSMTPReq = {} // server.clear-smtp + export type ClearSMTPRes = null + + export type TestSMTPReq = SetSMTPReq & { to: string } // server.test-smtp + export type TestSMTPRes = null + // sessions export type GetSessionsReq = {} // sessions.list diff --git a/web/projects/ui/src/app/services/api/embassy-api.service.ts b/web/projects/ui/src/app/services/api/embassy-api.service.ts index 551011533..5bbd4238a 100644 --- a/web/projects/ui/src/app/services/api/embassy-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-api.service.ts @@ -128,6 +128,14 @@ export abstract class ApiService { abstract resetTor(params: RR.ResetTorReq): Promise + // smtp + + abstract setSmtp(params: RR.SetSMTPReq): Promise + + abstract clearSmtp(params: RR.ClearSMTPReq): Promise + + abstract testSmtp(params: RR.TestSMTPReq): Promise + // marketplace URLs abstract registryRequest( diff --git a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts index 9893585a4..f61b217bf 100644 --- a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts @@ -382,6 +382,20 @@ export class LiveApiService extends ApiService { return this.rpcRequest({ method: 'wifi.delete', params }) } + // smtp + + async setSmtp(params: RR.SetSMTPReq): Promise { + return this.rpcRequest({ method: 'server.set-smtp', params }) + } + + async clearSmtp(params: RR.ClearSMTPReq): Promise { + return this.rpcRequest({ method: 'server.clear-smtp', params }) + } + + async testSmtp(params: RR.TestSMTPReq): Promise { + return this.rpcRequest({ method: 'server.test-smtp', params }) + } + // ssh async getSshKeys(params: RR.GetSSHKeysReq): Promise { diff --git a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 23296ad15..c2a30d1cb 100644 --- a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -557,6 +557,41 @@ export class MockApiService extends ApiService { return null } + // smtp + + async setSmtp(params: RR.SetSMTPReq): Promise { + await pauseFor(2000) + const patch = [ + { + op: PatchOp.REPLACE, + path: '/serverInfo/smtp', + value: params, + }, + ] + this.mockRevision(patch) + + return null + } + + async clearSmtp(params: RR.ClearSMTPReq): Promise { + await pauseFor(2000) + const patch = [ + { + op: PatchOp.REPLACE, + path: '/serverInfo/smtp', + value: null, + }, + ] + this.mockRevision(patch) + + return null + } + + async testSmtp(params: RR.TestSMTPReq): Promise { + await pauseFor(2000) + return null + } + // ssh async getSshKeys(params: RR.GetSSHKeysReq): Promise { From 5e103770fd83ce378397144d30518d1f9e28ff57 Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:58:50 +0000 Subject: [PATCH 10/35] rename some things in the sdk (#2809) * rename some things in the sdk * fix docs * rename some types exported from rust --- .../DockerProcedureContainer.ts | 2 +- .../SystemForEmbassy/polyfillEffects.ts | 6 +++--- core/startos/src/net/host/address.rs | 8 +++++++- core/startos/src/net/host/binding.rs | 9 +++++---- core/startos/src/net/network_interface.rs | 4 ++-- ...blicParams.ts => BindingSetPublicParams.ts} | 5 ++++- sdk/base/lib/osBindings/HostAddress.ts | 11 +++++++++++ .../NetworkInterfaceSetPublicParams.ts | 6 ++++++ sdk/base/lib/osBindings/index.ts | 4 +++- sdk/package/lib/StartSdk.ts | 18 +++++++----------- sdk/package/lib/mainFn/CommandController.ts | 2 +- sdk/package/lib/mainFn/Daemon.ts | 2 +- sdk/package/lib/mainFn/Daemons.ts | 2 +- sdk/package/lib/test/host.test.ts | 2 +- sdk/package/lib/util/SubContainer.ts | 10 +++++----- sdk/package/package-lock.json | 4 ++-- sdk/package/package.json | 2 +- 17 files changed, 61 insertions(+), 36 deletions(-) rename sdk/base/lib/osBindings/{SetPublicParams.ts => BindingSetPublicParams.ts} (55%) create mode 100644 sdk/base/lib/osBindings/HostAddress.ts create mode 100644 sdk/base/lib/osBindings/NetworkInterfaceSetPublicParams.ts diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/DockerProcedureContainer.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/DockerProcedureContainer.ts index 26e4dd8bf..806216786 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/DockerProcedureContainer.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/DockerProcedureContainer.ts @@ -43,7 +43,7 @@ export class DockerProcedureContainer { ) { const subcontainer = await SubContainer.of( effects, - { id: data.image }, + { imageId: data.image }, name, ) diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts index 7438070ea..5cbec945a 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/polyfillEffects.ts @@ -109,7 +109,7 @@ export const polyfillEffects = ( return startSdk .runCommand( effects, - { id: manifest.main.image }, + { imageId: manifest.main.image }, commands, {}, commands.join(" "), @@ -165,7 +165,7 @@ export const polyfillEffects = ( await startSdk .runCommand( effects, - { id: manifest.main.image }, + { imageId: manifest.main.image }, commands, { mounts: [ @@ -207,7 +207,7 @@ export const polyfillEffects = ( await startSdk .runCommand( effects, - { id: manifest.main.image }, + { imageId: manifest.main.image }, commands, { mounts: [ diff --git a/core/startos/src/net/host/address.rs b/core/startos/src/net/host/address.rs index 3d639b31e..fa41824a5 100644 --- a/core/startos/src/net/host/address.rs +++ b/core/startos/src/net/host/address.rs @@ -11,12 +11,18 @@ use crate::net::acme::AcmeProvider; use crate::prelude::*; use crate::util::serde::{display_serializable, HandlerExtSerde}; -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, TS)] +#[serde(rename_all = "kebab-case")] +#[serde(rename_all_fields = "camelCase")] +#[serde(tag = "kind")] +#[ts(export)] pub enum HostAddress { Onion { + #[ts(type = "string")] address: OnionAddressV3, }, Domain { + #[ts(type = "string")] address: InternedString, public: bool, acme: Option, diff --git a/core/startos/src/net/host/binding.rs b/core/startos/src/net/host/binding.rs index d56f607a9..08f9f68c4 100644 --- a/core/startos/src/net/host/binding.rs +++ b/core/startos/src/net/host/binding.rs @@ -221,9 +221,10 @@ pub async fn list_bindings( .de() } -#[derive(Deserialize, Serialize, Parser)] +#[derive(Deserialize, Serialize, Parser, TS)] #[serde(rename_all = "camelCase")] -pub struct SetPublicParams { +#[ts(export)] +pub struct BindingSetPublicParams { internal_port: u16, #[arg(long)] public: Option, @@ -231,10 +232,10 @@ pub struct SetPublicParams { pub async fn set_public( ctx: RpcContext, - SetPublicParams { + BindingSetPublicParams { internal_port, public, - }: SetPublicParams, + }: BindingSetPublicParams, (package, host): (PackageId, HostId), ) -> Result<(), Error> { ctx.db diff --git a/core/startos/src/net/network_interface.rs b/core/startos/src/net/network_interface.rs index 4f7696c97..920bdd4e4 100644 --- a/core/startos/src/net/network_interface.rs +++ b/core/startos/src/net/network_interface.rs @@ -114,7 +114,7 @@ async fn list_interfaces( #[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] #[ts(export)] -struct SetPublicParams { +struct NetworkInterfaceSetPublicParams { #[ts(type = "string")] interface: InternedString, public: Option, @@ -122,7 +122,7 @@ struct SetPublicParams { async fn set_public( ctx: RpcContext, - SetPublicParams { interface, public }: SetPublicParams, + NetworkInterfaceSetPublicParams { interface, public }: NetworkInterfaceSetPublicParams, ) -> Result<(), Error> { ctx.net_controller .net_iface diff --git a/sdk/base/lib/osBindings/SetPublicParams.ts b/sdk/base/lib/osBindings/BindingSetPublicParams.ts similarity index 55% rename from sdk/base/lib/osBindings/SetPublicParams.ts rename to sdk/base/lib/osBindings/BindingSetPublicParams.ts index 03bc3082b..077cf8510 100644 --- a/sdk/base/lib/osBindings/SetPublicParams.ts +++ b/sdk/base/lib/osBindings/BindingSetPublicParams.ts @@ -1,3 +1,6 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type SetPublicParams = { interface: string; public: boolean | null } +export type BindingSetPublicParams = { + internalPort: number + public: boolean | null +} diff --git a/sdk/base/lib/osBindings/HostAddress.ts b/sdk/base/lib/osBindings/HostAddress.ts new file mode 100644 index 000000000..fe16c89d7 --- /dev/null +++ b/sdk/base/lib/osBindings/HostAddress.ts @@ -0,0 +1,11 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { AcmeProvider } from "./AcmeProvider" + +export type HostAddress = + | { kind: "onion"; address: string } + | { + kind: "domain" + address: string + public: boolean + acme: AcmeProvider | null + } diff --git a/sdk/base/lib/osBindings/NetworkInterfaceSetPublicParams.ts b/sdk/base/lib/osBindings/NetworkInterfaceSetPublicParams.ts new file mode 100644 index 000000000..516bfc817 --- /dev/null +++ b/sdk/base/lib/osBindings/NetworkInterfaceSetPublicParams.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type NetworkInterfaceSetPublicParams = { + interface: string + public: boolean | null +} diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index c8b49d00a..3c16f6e70 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -38,6 +38,7 @@ export { BackupTargetFS } from "./BackupTargetFS" export { Base64 } from "./Base64" export { BindId } from "./BindId" export { BindInfo } from "./BindInfo" +export { BindingSetPublicParams } from "./BindingSetPublicParams" export { BindOptions } from "./BindOptions" export { BindParams } from "./BindParams" export { Blake3Commitment } from "./Blake3Commitment" @@ -97,6 +98,7 @@ export { Governor } from "./Governor" export { Guid } from "./Guid" export { HardwareRequirements } from "./HardwareRequirements" export { HealthCheckId } from "./HealthCheckId" +export { HostAddress } from "./HostAddress" export { HostId } from "./HostId" export { HostKind } from "./HostKind" export { HostnameInfo } from "./HostnameInfo" @@ -131,6 +133,7 @@ export { NamedHealthCheckResult } from "./NamedHealthCheckResult" export { NamedProgress } from "./NamedProgress" export { NetInfo } from "./NetInfo" export { NetworkInterfaceInfo } from "./NetworkInterfaceInfo" +export { NetworkInterfaceSetPublicParams } from "./NetworkInterfaceSetPublicParams" export { NetworkInterfaceType } from "./NetworkInterfaceType" export { OnionHostname } from "./OnionHostname" export { OsIndex } from "./OsIndex" @@ -176,7 +179,6 @@ export { SetIconParams } from "./SetIconParams" export { SetMainStatusStatus } from "./SetMainStatusStatus" export { SetMainStatus } from "./SetMainStatus" export { SetNameParams } from "./SetNameParams" -export { SetPublicParams } from "./SetPublicParams" export { SetStoreParams } from "./SetStoreParams" export { SetupExecuteParams } from "./SetupExecuteParams" export { SetupProgress } from "./SetupProgress" diff --git a/sdk/package/lib/StartSdk.ts b/sdk/package/lib/StartSdk.ts index 65ef23883..667e4297b 100644 --- a/sdk/package/lib/StartSdk.ts +++ b/sdk/package/lib/StartSdk.ts @@ -215,18 +215,14 @@ export class StartSdk { }), }, - host: { - // static: (effects: Effects, id: string) => - // new StaticHost({ id, effects }), - // single: (effects: Effects, id: string) => - // new SingleHost({ id, effects }), - multi: (effects: Effects, id: string) => new MultiHost({ id, effects }), + MultiHost: { + of: (effects: Effects, id: string) => new MultiHost({ id, effects }), }, nullIfEmpty, runCommand: async ( effects: Effects, image: { - id: keyof Manifest["images"] & T.ImageId + imageId: keyof Manifest["images"] & T.ImageId sharedRun?: boolean }, command: T.CommandType, @@ -548,7 +544,7 @@ export class StartSdk { inputSpecSpec, async ({ effects, input }) => { // ** UI multi-host ** - const uiMulti = sdk.host.multi(effects, 'ui-multi') + const uiMulti = sdk.MultiHost.of(effects, 'ui-multi') const uiMultiOrigin = await uiMulti.bindPort(80, { protocol: 'http', }) @@ -580,7 +576,7 @@ export class StartSdk { const uiReceipt = await uiMultiOrigin.export([primaryUi, adminUi]) // ** API multi-host ** - const apiMulti = sdk.host.multi(effects, 'api-multi') + const apiMulti = sdk.MultiHost.of(effects, 'api-multi') const apiMultiOrigin = await apiMulti.bindPort(5959, { protocol: 'http', }) @@ -685,7 +681,7 @@ export class StartSdk { of( effects: Effects, image: { - id: T.ImageId & keyof Manifest["images"] + imageId: T.ImageId & keyof Manifest["images"] sharedRun?: boolean }, name: string, @@ -1414,7 +1410,7 @@ export class StartSdk { export async function runCommand( effects: Effects, - image: { id: keyof Manifest["images"] & T.ImageId; sharedRun?: boolean }, + image: { imageId: keyof Manifest["images"] & T.ImageId; sharedRun?: boolean }, command: string | [string, ...string[]], options: CommandOptions & { mounts?: { path: string; options: MountOptions }[] diff --git a/sdk/package/lib/mainFn/CommandController.ts b/sdk/package/lib/mainFn/CommandController.ts index 498de2843..a7375b369 100644 --- a/sdk/package/lib/mainFn/CommandController.ts +++ b/sdk/package/lib/mainFn/CommandController.ts @@ -23,7 +23,7 @@ export class CommandController { effects: T.Effects, subcontainer: | { - id: keyof Manifest["images"] & T.ImageId + imageId: keyof Manifest["images"] & T.ImageId sharedRun?: boolean } | SubContainer, diff --git a/sdk/package/lib/mainFn/Daemon.ts b/sdk/package/lib/mainFn/Daemon.ts index 0cbc9cd94..864ae4122 100644 --- a/sdk/package/lib/mainFn/Daemon.ts +++ b/sdk/package/lib/mainFn/Daemon.ts @@ -22,7 +22,7 @@ export class Daemon { effects: T.Effects, subcontainer: | { - id: keyof Manifest["images"] & T.ImageId + imageId: keyof Manifest["images"] & T.ImageId sharedRun?: boolean } | SubContainer, diff --git a/sdk/package/lib/mainFn/Daemons.ts b/sdk/package/lib/mainFn/Daemons.ts index e18fa2314..8d0e6297a 100644 --- a/sdk/package/lib/mainFn/Daemons.ts +++ b/sdk/package/lib/mainFn/Daemons.ts @@ -53,7 +53,7 @@ type DaemonsParams< subcontainer: | { /** The ID of the image. Must be one of the image IDs declared in the manifest */ - id: keyof Manifest["images"] & T.ImageId + imageId: keyof Manifest["images"] & T.ImageId /** * Whether or not to share the `/run` directory with the parent container. * This is useful if you are trying to connect to a service that exposes a unix domain socket or auth cookie via the `/run` directory diff --git a/sdk/package/lib/test/host.test.ts b/sdk/package/lib/test/host.test.ts index 4492804ec..88ca7c4b6 100644 --- a/sdk/package/lib/test/host.test.ts +++ b/sdk/package/lib/test/host.test.ts @@ -5,7 +5,7 @@ import { sdk } from "../test/output.sdk" describe("host", () => { test("Testing that the types work", () => { async function test(effects: Effects) { - const foo = sdk.host.multi(effects, "foo") + const foo = sdk.MultiHost.of(effects, "foo") const fooOrigin = await foo.bindPort(80, { protocol: "http" as const, preferredExternalPort: 80, diff --git a/sdk/package/lib/util/SubContainer.ts b/sdk/package/lib/util/SubContainer.ts index f9b5a1084..77b31fec8 100644 --- a/sdk/package/lib/util/SubContainer.ts +++ b/sdk/package/lib/util/SubContainer.ts @@ -86,12 +86,12 @@ export class SubContainer implements ExecSpawnable { } static async of( effects: T.Effects, - image: { id: T.ImageId; sharedRun?: boolean }, + image: { imageId: T.ImageId; sharedRun?: boolean }, name: string, ) { - const { id, sharedRun } = image + const { imageId, sharedRun } = image const [rootfs, guid] = await effects.subcontainer.createFs({ - imageId: id as string, + imageId, name, }) @@ -111,12 +111,12 @@ export class SubContainer implements ExecSpawnable { await execFile("mount", ["--rbind", from, to]) } - return new SubContainer(effects, id, rootfs, guid) + return new SubContainer(effects, imageId, rootfs, guid) } static async with( effects: T.Effects, - image: { id: T.ImageId; sharedRun?: boolean }, + image: { imageId: T.ImageId; sharedRun?: boolean }, mounts: { options: MountOptions; path: string }[], name: string, fn: (subContainer: SubContainer) => Promise, diff --git a/sdk/package/package-lock.json b/sdk/package/package-lock.json index 58a37e357..6f2cf74d8 100644 --- a/sdk/package/package-lock.json +++ b/sdk/package/package-lock.json @@ -1,12 +1,12 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.3", + "version": "0.3.6-beta.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.3", + "version": "0.3.6-beta.4", "license": "MIT", "dependencies": { "@iarna/toml": "^2.2.5", diff --git a/sdk/package/package.json b/sdk/package/package.json index 1a68b9d1b..5e80f5a94 100644 --- a/sdk/package/package.json +++ b/sdk/package/package.json @@ -1,6 +1,6 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-beta.3", + "version": "0.3.6-beta.4", "description": "Software development kit to facilitate packaging services for StartOS", "main": "./package/lib/index.js", "types": "./package/lib/index.d.ts", From 0a9f1d2a27ffa87c0c12ec24141016cecd0332f0 Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:40:10 +0000 Subject: [PATCH 11/35] fix migration for alpha.10 (#2811) * fix migration for alpha.10 * fix binds * don't commit if db model does not match * stronger guard * better guard --- core/Cargo.lock | 2 +- core/startos/Cargo.toml | 4 +- core/startos/src/version/mod.rs | 8 +- core/startos/src/version/v0_3_6_alpha_11.rs | 83 +++++++++++++++++++++ web/package-lock.json | 4 +- web/package.json | 2 +- 6 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 core/startos/src/version/v0_3_6_alpha_11.rs diff --git a/core/Cargo.lock b/core/Cargo.lock index 41b912eaf..bc489c481 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -5920,7 +5920,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "start-os" -version = "0.3.6-alpha.10" +version = "0.3.6-alpha.11" dependencies = [ "aes 0.7.5", "async-acme", diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index a476db313..62453460a 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -14,7 +14,7 @@ keywords = [ name = "start-os" readme = "README.md" repository = "https://github.com/Start9Labs/start-os" -version = "0.3.6-alpha.10" +version = "0.3.6-alpha.11" license = "MIT" [lib] @@ -226,7 +226,7 @@ zbus = "5.1.1" zeroize = "1.6.0" mail-send = { git = "https://github.com/dr-bonez/mail-send.git", branch = "main" } rustls = "0.23.20" -rustls-pki-types = { version = "1.10.1", features = ["alloc"]} +rustls-pki-types = { version = "1.10.1", features = ["alloc"] } [profile.test] opt-level = 3 diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index ff7c3da99..3c1687ea9 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -10,6 +10,7 @@ use imbl_value::{to_value, InternedString}; use patch_db::json_ptr::ROOT; use crate::context::RpcContext; +use crate::db::model::Database; use crate::prelude::*; use crate::Error; @@ -28,8 +29,9 @@ mod v0_3_6_alpha_8; mod v0_3_6_alpha_9; mod v0_3_6_alpha_10; +mod v0_3_6_alpha_11; -pub type Current = v0_3_6_alpha_10::Version; // VERSION_BUMP +pub type Current = v0_3_6_alpha_11::Version; // VERSION_BUMP impl Current { #[instrument(skip(self, db))] @@ -52,6 +54,7 @@ impl Current { let pre_ups = PreUps::load(&from, &self).await?; db.apply_function(|mut db| { migrate_from_unchecked(&from, &self, pre_ups, &mut db)?; + from_value::(db.clone())?; Ok::<_, Error>((db, ())) }) .await?; @@ -109,6 +112,7 @@ enum Version { V0_3_6_alpha_8(Wrapper), V0_3_6_alpha_9(Wrapper), V0_3_6_alpha_10(Wrapper), + V0_3_6_alpha_11(Wrapper), Other(exver::Version), } @@ -143,6 +147,7 @@ impl Version { Self::V0_3_6_alpha_8(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_9(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_10(v) => DynVersion(Box::new(v.0)), + Self::V0_3_6_alpha_11(v) => DynVersion(Box::new(v.0)), Self::Other(v) => { return Err(Error::new( eyre!("unknown version {v}"), @@ -169,6 +174,7 @@ impl Version { Version::V0_3_6_alpha_8(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_9(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_10(Wrapper(x)) => x.semver(), + Version::V0_3_6_alpha_11(Wrapper(x)) => x.semver(), Version::Other(x) => x.clone(), } } diff --git a/core/startos/src/version/v0_3_6_alpha_11.rs b/core/startos/src/version/v0_3_6_alpha_11.rs new file mode 100644 index 000000000..8a6dedd6e --- /dev/null +++ b/core/startos/src/version/v0_3_6_alpha_11.rs @@ -0,0 +1,83 @@ +use exver::{PreReleaseSegment, VersionRange}; +use imbl_value::json; + +use super::v0_3_5::V0_3_0_COMPAT; +use super::{v0_3_6_alpha_10, VersionT}; +use crate::prelude::*; + +lazy_static::lazy_static! { + static ref V0_3_6_alpha_11: exver::Version = exver::Version::new( + [0, 3, 6], + [PreReleaseSegment::String("alpha".into()), 11.into()] + ); +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct Version; + +impl VersionT for Version { + type Previous = v0_3_6_alpha_10::Version; + type PreUpRes = (); + + async fn pre_up(self) -> Result { + Ok(()) + } + fn semver(self) -> exver::Version { + V0_3_6_alpha_11.clone() + } + fn compat(self) -> &'static VersionRange { + &V0_3_0_COMPAT + } + fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { + let acme = std::mem::replace( + &mut db["public"]["serverInfo"]["acme"], + Value::Object(Default::default()), + ); + if !acme.is_null() && acme["provider"].as_str().is_some() { + db["public"]["serverInfo"]["acme"] + [&acme["provider"].as_str().or_not_found("provider")?] = + json!({ "contact": &acme["contact"] }); + } + + for (_, package) in db["public"]["packageData"] + .as_object_mut() + .ok_or_else(|| { + Error::new( + eyre!("expected public.packageData to be an object"), + ErrorKind::Database, + ) + })? + .iter_mut() + { + for (_, host) in package["hosts"] + .as_object_mut() + .ok_or_else(|| { + Error::new( + eyre!("expected public.packageData[id].hosts to be an object"), + ErrorKind::Database, + ) + })? + .iter_mut() + { + for (_, bind) in host["bindings"] + .as_object_mut() + .ok_or_else(|| { + Error::new( + eyre!("expected public.packageData[id].hosts[hostId].bindings to be an object"), + ErrorKind::Database, + ) + })? + .iter_mut() + { + bind["net"] = bind["lan"].clone(); + bind["net"]["public"] = Value::Bool(false); + } + } + } + + Ok(()) + } + fn down(self, _db: &mut Value) -> Result<(), Error> { + Ok(()) + } +} diff --git a/web/package-lock.json b/web/package-lock.json index ee7a93d8d..740020a3a 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.10", + "version": "0.3.6-alpha.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.3.6-alpha.10", + "version": "0.3.6-alpha.11", "license": "MIT", "dependencies": { "@angular/animations": "^14.1.0", diff --git a/web/package.json b/web/package.json index d71b2f0a2..800297407 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.10", + "version": "0.3.6-alpha.11", "author": "Start9 Labs, Inc", "homepage": "https://start9.com/", "license": "MIT", From 479797361e7fbda3f69927368a0d35a76e314828 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 21 Jan 2025 20:46:36 -0700 Subject: [PATCH 12/35] add clearnet functionality to frontend (#2814) * add clearnet functionality to frontend * add pattern and add sync db on rpcs * add domain pattern * show acme name instead of url if known * dont blow up if domain not present after delete * use common name for letsencrypt * normalize urls * refactor start-os ui net service * backend migration and rpcs for serverInfo.host * fix cors * implement clearnet for main startos ui * ability to add and remove tor addresses, including vanity * add guard to prevent duplicate addresses * misc bugfixes * better heuristics for launching UIs * fix ipv6 mocks * fix ipv6 display bug * rewrite url selection for launch ui --------- Co-authored-by: Aiden McClelland --- .../Systems/SystemForEmbassy/MainLoop.ts | 1 - .../Systems/SystemForEmbassy/index.ts | 1 + core/Cargo.lock | 327 ++++++------- core/helpers/Cargo.toml | 2 +- core/models/Cargo.toml | 2 +- core/models/src/data_url.rs | 2 +- core/models/src/errors.rs | 6 +- core/models/src/id/invalid_id.rs | 6 +- core/models/src/id/mod.rs | 6 +- core/startos/Cargo.toml | 6 +- core/startos/src/account.rs | 34 +- core/startos/src/backup/os.rs | 10 +- core/startos/src/backup/restore.rs | 6 +- core/startos/src/bins/start_init.rs | 6 +- core/startos/src/context/config.rs | 3 - core/startos/src/context/rpc.rs | 57 ++- core/startos/src/context/setup.rs | 8 +- core/startos/src/db/model/public.rs | 54 ++- core/startos/src/init.rs | 80 ++-- core/startos/src/lib.rs | 5 +- core/startos/src/middleware/cors.rs | 10 +- core/startos/src/net/acme.rs | 69 ++- core/startos/src/net/dns.rs | 57 ++- core/startos/src/net/host/address.rs | 158 +++---- core/startos/src/net/host/binding.rs | 59 +-- core/startos/src/net/host/mod.rs | 136 ++++-- core/startos/src/net/keys.rs | 4 +- core/startos/src/net/net_controller.rs | 428 ++++++++++-------- core/startos/src/net/network_interface.rs | 58 ++- core/startos/src/net/vhost.rs | 29 +- core/startos/src/net/wifi.rs | 3 +- core/startos/src/service/effects/net/bind.rs | 19 +- core/startos/src/service/effects/net/info.rs | 3 +- core/startos/src/service/mod.rs | 21 +- .../src/service/persistent_container.rs | 4 +- core/startos/src/service/service_actor.rs | 32 -- core/startos/src/service/service_map.rs | 11 +- core/startos/src/setup.rs | 15 +- core/startos/src/util/sync.rs | 8 + core/startos/src/version/mod.rs | 6 +- core/startos/src/version/v0_3_6_alpha_0.rs | 4 +- core/startos/src/version/v0_3_6_alpha_12.rs | 68 +++ package-lock.json | 6 - patch-db | 2 +- sdk/base/lib/interfaces/Host.ts | 31 +- sdk/base/lib/interfaces/Origin.ts | 6 +- sdk/base/lib/osBindings/BindParams.ts | 2 - sdk/base/lib/osBindings/Host.ts | 2 - sdk/base/lib/osBindings/HostKind.ts | 3 - sdk/base/lib/osBindings/ServerInfo.ts | 8 +- sdk/base/lib/osBindings/SetupResult.ts | 2 +- sdk/base/lib/osBindings/index.ts | 31 +- sdk/base/lib/util/patterns.ts | 29 +- sdk/base/lib/util/regexes.ts | 73 ++- system-images/compat/Cargo.toml | 2 +- web/package-lock.json | 6 +- web/package.json | 2 +- .../download-doc/download-doc.component.html | 2 +- .../src/app/pages/success/success.page.ts | 8 +- .../src/app/services/api/mock-api.service.ts | 4 +- .../shared/src/types/workspace-config.ts | 2 +- .../app/app/preloader/preloader.component.ts | 2 +- .../form-select/form-select.component.html | 2 +- .../interface-info.component.html | 62 +++ .../interface-info.component.scss | 3 + .../interface-info.component.ts | 393 ++++++++++++++++ .../interface-info/interface-info.module.ts | 11 + .../app-interfaces-item.component.html | 44 -- .../app-interfaces/app-interfaces.module.ts | 10 +- .../app-interfaces/app-interfaces.page.html | 15 +- .../app-interfaces/app-interfaces.page.scss | 3 - .../app-interfaces/app-interfaces.page.ts | 145 +----- .../pages/server-routes/acme/acme.module.ts | 18 + .../pages/server-routes/acme/acme.page.html | 56 +++ .../pages/server-routes/acme/acme.page.scss | 0 .../app/pages/server-routes/acme/acme.page.ts | 117 +++++ .../server-routes/server-routing.module.ts | 5 + .../server-show/server-show.page.ts | 9 + .../server-specs/server-specs.module.ts | 2 + .../server-specs/server-specs.page.html | 71 +-- .../server-specs/server-specs.page.ts | 50 +- .../ui/src/app/services/api/api.fixures.ts | 51 ++- .../ui/src/app/services/api/api.types.ts | 74 +++ .../app/services/api/embassy-api.service.ts | 44 ++ .../services/api/embassy-live-api.service.ts | 112 +++++ .../services/api/embassy-mock-api.service.ts | 289 +++++++++++- .../ui/src/app/services/api/mock-patch.ts | 171 ++++++- .../ui/src/app/services/config.service.ts | 214 +++++++-- .../ui/src/app/services/form.service.ts | 2 +- web/projects/ui/src/app/util/acme.ts | 21 + 90 files changed, 2838 insertions(+), 1203 deletions(-) create mode 100644 core/startos/src/version/v0_3_6_alpha_12.rs delete mode 100644 package-lock.json delete mode 100644 sdk/base/lib/osBindings/HostKind.ts create mode 100644 web/projects/ui/src/app/components/interface-info/interface-info.component.html create mode 100644 web/projects/ui/src/app/components/interface-info/interface-info.component.scss create mode 100644 web/projects/ui/src/app/components/interface-info/interface-info.component.ts create mode 100644 web/projects/ui/src/app/components/interface-info/interface-info.module.ts delete mode 100644 web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces-item.component.html create mode 100644 web/projects/ui/src/app/pages/server-routes/acme/acme.module.ts create mode 100644 web/projects/ui/src/app/pages/server-routes/acme/acme.page.html create mode 100644 web/projects/ui/src/app/pages/server-routes/acme/acme.page.scss create mode 100644 web/projects/ui/src/app/pages/server-routes/acme/acme.page.ts create mode 100644 web/projects/ui/src/app/util/acme.ts diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts index b6fe39854..fa76a1f84 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts @@ -113,7 +113,6 @@ export class MainLoop { })) .find((conf) => conf.internal == internalPort) await effects.bind({ - kind: "multi", id: interfaceId, internalPort, preferredExternalPort: torConf?.external || internalPort, diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts index e74ef317d..bc2da8871 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts @@ -401,6 +401,7 @@ export class SystemForEmbassy implements System { return [ port, { + protocol: null, secure: null, preferredExternalPort: Number.parseInt( torPort || lanPort || String(port), diff --git a/core/Cargo.lock b/core/Cargo.lock index bc489c481..3810d0d8d 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -163,11 +163,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys 0.59.0", ] @@ -237,7 +238,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -249,7 +250,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -265,7 +266,7 @@ dependencies = [ "pem", "rcgen", "ring 0.17.8", - "rustls 0.23.20", + "rustls 0.23.21", "rustls-pemfile 2.2.0", "serde", "serde_json", @@ -404,7 +405,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -444,7 +445,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -461,7 +462,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -487,9 +488,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f409eb70b561706bf8abba8ca9c112729c481595893fd06a2dd9af8ed8441148" +checksum = "1ea835662a0af02443aa1396d39be523bbf8f11ee6fad20329607c480bea48c3" dependencies = [ "aws-lc-sys", "paste", @@ -498,9 +499,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923ded50f602b3007e5e63e3f094c479d9c8a9b42d7f4034e4afe456aa48bfd2" +checksum = "71b2ddd3ada61a305e1d8bb6c005d1eaa7d14d903681edfc400406d523a9b491" dependencies = [ "bindgen", "cc", @@ -717,7 +718,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -730,7 +731,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.95", + "syn 2.0.96", "which", ] @@ -772,9 +773,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" dependencies = [ "serde", ] @@ -946,9 +947,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cc" -version = "1.2.7" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" dependencies = [ "jobserver", "libc", @@ -1088,7 +1089,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1382,7 +1383,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "crossterm_winapi", "futures-core", "mio", @@ -1497,7 +1498,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1521,7 +1522,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1532,14 +1533,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" [[package]] name = "deflate64" @@ -1569,7 +1570,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1606,7 +1607,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1627,7 +1628,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1640,7 +1641,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1693,7 +1694,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1882,14 +1883,14 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" dependencies = [ "enumflags2_derive", "serde", @@ -1897,13 +1898,13 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -2065,7 +2066,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", - "miniz_oxide 0.8.2", + "miniz_oxide 0.8.3", ] [[package]] @@ -2197,9 +2198,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ "fastrand", "futures-core", @@ -2216,7 +2217,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -2340,7 +2341,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8283e7331b8c93b9756e0cfdbcfb90312852f953c6faf9bf741e684cc3b6ad69" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "crc", "log", "uuid", @@ -2738,7 +2739,7 @@ dependencies = [ "http 1.2.0", "hyper 1.5.2", "hyper-util", - "rustls 0.23.20", + "rustls 0.23.21", "rustls-pki-types", "tokio", "tokio-rustls 0.26.1", @@ -2930,7 +2931,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3017,6 +3018,18 @@ dependencies = [ name = "imbl-value" version = "0.1.1" source = "git+https://github.com/Start9Labs/imbl-value.git#1900943e17116def03bf00bff05cf12e54d810bc" +dependencies = [ + "imbl", + "serde", + "serde_json", + "yasi", +] + +[[package]] +name = "imbl-value" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3431be119ebf79f4bd0ce420dfa66aaeffbc4688f79c796237dc1f3b2d6d71" dependencies = [ "imbl", "serde", @@ -3281,9 +3294,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -3293,7 +3306,7 @@ dependencies = [ name = "json-patch" version = "0.2.7-alpha.0" dependencies = [ - "imbl-value", + "imbl-value 0.1.2", "json-ptr", "serde", "treediff", @@ -3304,7 +3317,7 @@ name = "json-ptr" version = "0.1.0" dependencies = [ "imbl", - "imbl-value", + "imbl-value 0.1.2", "serde", "thiserror 1.0.69", ] @@ -3314,7 +3327,7 @@ name = "jsonpath_lib" version = "0.3.0" source = "git+https://github.com/Start9Labs/jsonpath.git#1cacbd64afa2e1941a21fef06bad14317ba92f30" dependencies = [ - "imbl-value", + "imbl-value 0.1.1", "log", "serde", "serde_json", @@ -3432,7 +3445,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "libc", "redox_syscall 0.5.8", ] @@ -3496,9 +3509,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "lru-cache" @@ -3580,7 +3593,7 @@ dependencies = [ "mail-builder", "md5", "rand 0.8.5", - "rustls 0.23.20", + "rustls 0.23.21", "rustls-pki-types", "smtp-proto", "tokio", @@ -3703,9 +3716,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" dependencies = [ "adler2", ] @@ -3741,7 +3754,7 @@ dependencies = [ "regex", "reqwest", "rpc-toolkit", - "rustls 0.23.20", + "rustls 0.23.21", "serde", "serde_json", "sqlx", @@ -3819,7 +3832,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cfg-if", "cfg_aliases", "libc", @@ -3993,7 +4006,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4051,7 +4064,7 @@ version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cfg-if", "foreign-types", "libc", @@ -4068,7 +4081,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4202,7 +4215,7 @@ dependencies = [ "fd-lock-rs", "futures", "imbl", - "imbl-value", + "imbl-value 0.1.2", "json-patch", "json-ptr", "lazy_static", @@ -4277,7 +4290,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.10", + "thiserror 2.0.11", "ucd-trie", ] @@ -4301,7 +4314,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4357,7 +4370,7 @@ checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4454,12 +4467,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4496,9 +4509,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -4509,7 +4522,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "chrono", "flate2", "hex", @@ -4524,7 +4537,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "chrono", "hex", ] @@ -4537,7 +4550,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.6.0", + "bitflags 2.8.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -4557,7 +4570,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4580,7 +4593,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4785,7 +4798,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", ] [[package]] @@ -4967,8 +4980,8 @@ dependencies = [ [[package]] name = "rpc-toolkit" -version = "0.2.3" -source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=refactor%2Fno-dyn-ctx#21e35d85fb8f5de0e046c7ab5266236c2b639a4b" +version = "0.3.0" +source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=master#0747acc54b3dafa8689db1365fba5b28a03806b1" dependencies = [ "async-stream", "async-trait", @@ -4977,7 +4990,7 @@ dependencies = [ "futures", "http 1.2.0", "http-body-util", - "imbl-value", + "imbl-value 0.1.2", "itertools 0.12.1", "lazy_format", "lazy_static", @@ -5071,7 +5084,7 @@ version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "errno 0.3.10", "libc", "linux-raw-sys", @@ -5106,9 +5119,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ "aws-lc-rs", "log", @@ -5194,7 +5207,7 @@ dependencies = [ "futures-util", "pin-project", "thingbuf", - "thiserror 2.0.10", + "thiserror 2.0.11", "unicode-segmentation", "unicode-width 0.2.0", ] @@ -5259,7 +5272,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "core-foundation", "core-foundation-sys", "libc", @@ -5319,7 +5332,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5364,7 +5377,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5415,7 +5428,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5745,7 +5758,7 @@ checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", "base64 0.21.7", - "bitflags 2.6.0", + "bitflags 2.8.0", "byteorder", "bytes", "chrono", @@ -5788,7 +5801,7 @@ checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", "base64 0.21.7", - "bitflags 2.6.0", + "bitflags 2.8.0", "byteorder", "chrono", "crc", @@ -5866,7 +5879,7 @@ dependencies = [ "quote", "regex-syntax 0.6.29", "strsim 0.10.0", - "syn 2.0.95", + "syn 2.0.96", "unicode-width 0.1.14", ] @@ -5920,7 +5933,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "start-os" -version = "0.3.6-alpha.11" +version = "0.3.6-alpha.12" dependencies = [ "aes 0.7.5", "async-acme", @@ -5965,7 +5978,7 @@ dependencies = [ "hyper-util", "id-pool", "imbl", - "imbl-value", + "imbl-value 0.1.2", "include_dir", "indexmap 2.7.0", "indicatif", @@ -6013,7 +6026,7 @@ dependencies = [ "rpassword", "rpc-toolkit", "rust-argon2", - "rustls 0.23.20", + "rustls 0.23.21", "rustls-pki-types", "rustyline-async", "semver", @@ -6121,9 +6134,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.95" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -6153,7 +6166,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -6162,7 +6175,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "core-foundation", "system-configuration-sys", ] @@ -6260,11 +6273,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.10", + "thiserror-impl 2.0.11", ] [[package]] @@ -6275,18 +6288,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "thiserror-impl" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -6412,7 +6425,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -6452,7 +6465,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ - "rustls 0.23.20", + "rustls 0.23.21", "tokio", ] @@ -6589,7 +6602,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.22", + "winnow 0.6.24", ] [[package]] @@ -6706,7 +6719,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -6858,7 +6871,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "termcolor", ] @@ -6928,7 +6941,7 @@ checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -7095,18 +7108,18 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" dependencies = [ "getrandom 0.2.15", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vcpkg" @@ -7168,34 +7181,35 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", @@ -7206,9 +7220,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7216,22 +7230,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-streams" @@ -7248,9 +7265,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -7538,9 +7555,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.22" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" dependencies = [ "memchr", ] @@ -7691,15 +7708,15 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] [[package]] name = "zbus" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb67eadba43784b6fb14857eba0d8fc518686d3ee537066eb6086dc318e2c8a1" +checksum = "192a0d989036cd60a1e91a54c9851fb9ad5bd96125d41803eed79d2e2ef74bd7" dependencies = [ "async-broadcast", "async-executor", @@ -7724,7 +7741,7 @@ dependencies = [ "tracing", "uds_windows", "windows-sys 0.59.0", - "winnow 0.6.22", + "winnow 0.6.24", "xdg-home", "zbus_macros", "zbus_names", @@ -7733,14 +7750,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d49ebc960ceb660f2abe40a5904da975de6986f2af0d7884b39eec6528c57" +checksum = "3685b5c81fce630efc3e143a4ded235b107f1b1cdf186c3f115529e5e5ae4265" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "zbus_names", "zvariant", "zvariant_utils", @@ -7748,13 +7765,13 @@ dependencies = [ [[package]] name = "zbus_names" -version = "4.1.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856b7a38811f71846fd47856ceee8bccaec8399ff53fb370247e66081ace647b" +checksum = "519629a3f80976d89c575895b05677cbc45eaf9f70d62a364d819ba646409cc8" dependencies = [ "serde", "static_assertions", - "winnow 0.6.22", + "winnow 0.6.24", "zvariant", ] @@ -7776,7 +7793,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -7796,7 +7813,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -7817,7 +7834,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -7839,7 +7856,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -7864,7 +7881,7 @@ dependencies = [ "pbkdf2", "rand 0.8.5", "sha1", - "thiserror 2.0.10", + "thiserror 2.0.11", "time", "zeroize", "zopfli", @@ -7915,42 +7932,42 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.1.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f" +checksum = "55e6b9b5f1361de2d5e7d9fd1ee5f6f7fcb6060618a1f82f3472f58f2b8d4be9" dependencies = [ "endi", "enumflags2", "serde", "static_assertions", - "winnow 0.6.22", + "winnow 0.6.24", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "5.1.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916" +checksum = "573a8dd76961957108b10f7a45bac6ab1ea3e9b7fe01aff88325dc57bb8f5c8b" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "3.0.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6" +checksum = "ddd46446ea2a1f353bfda53e35f17633afa79f4fe290a611c94645c69fe96a50" dependencies = [ "proc-macro2", "quote", "serde", "static_assertions", - "syn 2.0.95", - "winnow 0.6.22", + "syn 2.0.96", + "winnow 0.6.24", ] diff --git a/core/helpers/Cargo.toml b/core/helpers/Cargo.toml index 9af19018e..caf4b3eef 100644 --- a/core/helpers/Cargo.toml +++ b/core/helpers/Cargo.toml @@ -11,7 +11,7 @@ futures = "0.3.28" lazy_async_pool = "0.3.3" models = { path = "../models" } pin-project = "1.1.3" -rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "refactor/no-dyn-ctx" } +rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" } serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" tokio = { version = "1", features = ["full"] } diff --git a/core/models/Cargo.toml b/core/models/Cargo.toml index 5defd1986..9e216bc60 100644 --- a/core/models/Cargo.toml +++ b/core/models/Cargo.toml @@ -24,7 +24,7 @@ patch-db = { version = "*", path = "../../patch-db/patch-db", features = [ rand = "0.8.5" regex = "1.10.2" reqwest = "0.12" -rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "refactor/no-dyn-ctx" } +rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" } rustls = "0.23" serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" diff --git a/core/models/src/data_url.rs b/core/models/src/data_url.rs index 9757d7f6a..8a95c993e 100644 --- a/core/models/src/data_url.rs +++ b/core/models/src/data_url.rs @@ -168,6 +168,6 @@ fn doesnt_reallocate() { mime: InternedString::intern("png"), data: Cow::Borrowed(&random[..i]), }; - assert_eq!(dbg!(icon.to_string()).capacity(), icon.data_url_len()); + assert_eq!(icon.to_string().capacity(), icon.data_url_len()); } } diff --git a/core/models/src/errors.rs b/core/models/src/errors.rs index e7b73b0ec..21ff5072b 100644 --- a/core/models/src/errors.rs +++ b/core/models/src/errors.rs @@ -45,7 +45,7 @@ pub enum ErrorKind { ConfigGen = 27, ParseNumber = 28, Database = 29, - InvalidPackageId = 30, + InvalidId = 30, InvalidSignature = 31, Backup = 32, Restore = 33, @@ -125,7 +125,7 @@ impl ErrorKind { ConfigGen => "Config Generation Error", ParseNumber => "Number Parsing Error", Database => "Database Error", - InvalidPackageId => "Invalid Package ID", + InvalidId => "Invalid ID", InvalidSignature => "Invalid Signature", Backup => "Backup Error", Restore => "Restore Error", @@ -226,7 +226,7 @@ impl From for Error { } impl From for Error { fn from(err: InvalidId) -> Self { - Error::new(err, ErrorKind::InvalidPackageId) + Error::new(err, ErrorKind::InvalidId) } } impl From for Error { diff --git a/core/models/src/id/invalid_id.rs b/core/models/src/id/invalid_id.rs index d2cc82bd5..4a6f0f2e7 100644 --- a/core/models/src/id/invalid_id.rs +++ b/core/models/src/id/invalid_id.rs @@ -1,3 +1,5 @@ +use yasi::InternedString; + #[derive(Debug, thiserror::Error)] -#[error("Invalid ID")] -pub struct InvalidId; +#[error("Invalid ID: {0}")] +pub struct InvalidId(pub(super) InternedString); diff --git a/core/models/src/id/mod.rs b/core/models/src/id/mod.rs index 90dbc978c..0c313973f 100644 --- a/core/models/src/id/mod.rs +++ b/core/models/src/id/mod.rs @@ -43,7 +43,7 @@ impl TryFrom for Id { if ID_REGEX.is_match(&value) { Ok(Id(value)) } else { - Err(InvalidId) + Err(InvalidId(value)) } } } @@ -53,7 +53,7 @@ impl TryFrom for Id { if ID_REGEX.is_match(&value) { Ok(Id(InternedString::intern(value))) } else { - Err(InvalidId) + Err(InvalidId(InternedString::intern(value))) } } } @@ -63,7 +63,7 @@ impl TryFrom<&str> for Id { if ID_REGEX.is_match(value) { Ok(Id(InternedString::intern(value))) } else { - Err(InvalidId) + Err(InvalidId(InternedString::intern(value))) } } } diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index 62453460a..909389c12 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -14,7 +14,7 @@ keywords = [ name = "start-os" readme = "README.md" repository = "https://github.com/Start9Labs/start-os" -version = "0.3.6-alpha.11" +version = "0.3.6-alpha.12" license = "MIT" [lib] @@ -117,7 +117,7 @@ id-pool = { version = "0.2.2", default-features = false, features = [ "u16", ] } imbl = "2.0.3" -imbl-value = { git = "https://github.com/Start9Labs/imbl-value.git" } +imbl-value = "0.1.2" include_dir = { version = "0.7.3", features = ["metadata"] } indexmap = { version = "2.0.2", features = ["serde"] } indicatif = { version = "0.17.7", features = ["tokio"] } @@ -172,7 +172,7 @@ regex = "1.10.2" reqwest = { version = "0.12.4", features = ["stream", "json", "socks"] } reqwest_cookie_store = "0.8.0" rpassword = "7.2.0" -rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "refactor/no-dyn-ctx" } +rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" } rust-argon2 = "2.0.0" rustyline-async = "0.4.1" semver = { version = "1.0.20", features = ["serde"] } diff --git a/core/startos/src/account.rs b/core/startos/src/account.rs index 9e755342f..389589667 100644 --- a/core/startos/src/account.rs +++ b/core/startos/src/account.rs @@ -24,7 +24,7 @@ pub struct AccountInfo { pub server_id: String, pub hostname: Hostname, pub password: String, - pub tor_key: TorSecretKeyV3, + pub tor_keys: Vec, pub root_ca_key: PKey, pub root_ca_cert: X509, pub ssh_key: ssh_key::PrivateKey, @@ -34,7 +34,7 @@ impl AccountInfo { pub fn new(password: &str, start_time: SystemTime) -> Result { let server_id = generate_id(); let hostname = generate_hostname(); - let tor_key = TorSecretKeyV3::generate(); + let tor_key = vec![TorSecretKeyV3::generate()]; let root_ca_key = generate_key()?; let root_ca_cert = make_root_cert(&root_ca_key, &hostname, start_time)?; let ssh_key = ssh_key::PrivateKey::from(ssh_key::private::Ed25519Keypair::random( @@ -45,7 +45,7 @@ impl AccountInfo { server_id, hostname, password: hash_password(password)?, - tor_key, + tor_keys: tor_key, root_ca_key, root_ca_cert, ssh_key, @@ -58,8 +58,11 @@ impl AccountInfo { let hostname = Hostname(db.as_public().as_server_info().as_hostname().de()?); let password = db.as_private().as_password().de()?; let key_store = db.as_private().as_key_store(); - let tor_addr = db.as_public().as_server_info().as_onion_address().de()?; - let tor_key = key_store.as_onion().get_key(&tor_addr)?; + let tor_addrs = db.as_public().as_server_info().as_host().as_onions().de()?; + let tor_keys = tor_addrs + .into_iter() + .map(|tor_addr| key_store.as_onion().get_key(&tor_addr)) + .collect::>()?; let cert_store = key_store.as_local_certs(); let root_ca_key = cert_store.as_root_key().de()?.0; let root_ca_cert = cert_store.as_root_cert().de()?.0; @@ -70,7 +73,7 @@ impl AccountInfo { server_id, hostname, password, - tor_key, + tor_keys, root_ca_key, root_ca_cert, ssh_key, @@ -82,17 +85,16 @@ impl AccountInfo { let server_info = db.as_public_mut().as_server_info_mut(); server_info.as_id_mut().ser(&self.server_id)?; server_info.as_hostname_mut().ser(&self.hostname.0)?; - server_info - .as_lan_address_mut() - .ser(&self.hostname.lan_address().parse()?)?; server_info .as_pubkey_mut() .ser(&self.ssh_key.public_key().to_openssh()?)?; - let onion_address = self.tor_key.public().get_onion_address(); - server_info.as_onion_address_mut().ser(&onion_address)?; - server_info - .as_tor_address_mut() - .ser(&format!("https://{onion_address}").parse()?)?; + server_info.as_host_mut().as_onions_mut().ser( + &self + .tor_keys + .iter() + .map(|tor_key| tor_key.public().get_onion_address()) + .collect(), + )?; db.as_private_mut().as_password_mut().ser(&self.password)?; db.as_private_mut() .as_ssh_privkey_mut() @@ -101,7 +103,9 @@ impl AccountInfo { .as_compat_s9pk_key_mut() .ser(Pem::new_ref(&self.compat_s9pk_key))?; let key_store = db.as_private_mut().as_key_store_mut(); - key_store.as_onion_mut().insert_key(&self.tor_key)?; + for tor_key in &self.tor_keys { + key_store.as_onion_mut().insert_key(tor_key)?; + } let cert_store = key_store.as_local_certs_mut(); cert_store .as_root_key_mut() diff --git a/core/startos/src/backup/os.rs b/core/startos/src/backup/os.rs index 6f08c5f43..324543fb8 100644 --- a/core/startos/src/backup/os.rs +++ b/core/startos/src/backup/os.rs @@ -85,7 +85,7 @@ impl OsBackupV0 { &mut rand::thread_rng(), ssh_key::Algorithm::Ed25519, )?, - tor_key: TorSecretKeyV3::from(self.tor_key.0), + tor_keys: vec![TorSecretKeyV3::from(self.tor_key.0)], compat_s9pk_key: ed25519_dalek::SigningKey::generate(&mut rand::thread_rng()), }, ui: self.ui, @@ -114,7 +114,7 @@ impl OsBackupV1 { root_ca_key: self.root_ca_key.0, root_ca_cert: self.root_ca_cert.0, ssh_key: ssh_key::PrivateKey::from(Ed25519Keypair::from_seed(&self.net_key.0)), - tor_key: TorSecretKeyV3::from(ed25519_expand_key(&self.net_key.0)), + tor_keys: vec![TorSecretKeyV3::from(ed25519_expand_key(&self.net_key.0))], compat_s9pk_key: ed25519_dalek::SigningKey::from_bytes(&self.net_key), }, ui: self.ui, @@ -132,7 +132,7 @@ struct OsBackupV2 { root_ca_key: Pem>, // PEM Encoded OpenSSL Key root_ca_cert: Pem, // PEM Encoded OpenSSL X509 Certificate ssh_key: Pem, // PEM Encoded OpenSSH Key - tor_key: TorSecretKeyV3, // Base64 Encoded Ed25519 Expanded Secret Key + tor_keys: Vec, // Base64 Encoded Ed25519 Expanded Secret Key compat_s9pk_key: Pem, // PEM Encoded ED25519 Key ui: Value, // JSON Value } @@ -146,7 +146,7 @@ impl OsBackupV2 { root_ca_key: self.root_ca_key.0, root_ca_cert: self.root_ca_cert.0, ssh_key: self.ssh_key.0, - tor_key: self.tor_key, + tor_keys: self.tor_keys, compat_s9pk_key: self.compat_s9pk_key.0, }, ui: self.ui, @@ -159,7 +159,7 @@ impl OsBackupV2 { root_ca_key: Pem(backup.account.root_ca_key.clone()), root_ca_cert: Pem(backup.account.root_ca_cert.clone()), ssh_key: Pem(backup.account.ssh_key.clone()), - tor_key: backup.account.tor_key.clone(), + tor_keys: backup.account.tor_keys.clone(), compat_s9pk_key: Pem(backup.account.compat_s9pk_key.clone()), ui: backup.ui.clone(), } diff --git a/core/startos/src/backup/restore.rs b/core/startos/src/backup/restore.rs index e2e9e2158..21f154b60 100644 --- a/core/startos/src/backup/restore.rs +++ b/core/startos/src/backup/restore.rs @@ -18,7 +18,7 @@ use crate::db::model::Database; use crate::disk::mount::backup::BackupMountGuard; use crate::disk::mount::filesystem::ReadWrite; use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard}; -use crate::init::{init, InitResult}; +use crate::init::init; use crate::prelude::*; use crate::s9pk::S9pk; use crate::service::service_map::DownloadInstallFuture; @@ -109,13 +109,13 @@ pub async fn recover_full_embassy( db.put(&ROOT, &Database::init(&os_backup.account)?).await?; drop(db); - let InitResult { net_ctrl } = init(&ctx.webserver, &ctx.config, init_phases).await?; + let init_result = init(&ctx.webserver, &ctx.config, init_phases).await?; let rpc_ctx = RpcContext::init( &ctx.webserver, &ctx.config, disk_guid.clone(), - Some(net_ctrl), + Some(init_result), rpc_ctx_phases, ) .await?; diff --git a/core/startos/src/bins/start_init.rs b/core/startos/src/bins/start_init.rs index 7ff903090..fdd0e075d 100644 --- a/core/startos/src/bins/start_init.rs +++ b/core/startos/src/bins/start_init.rs @@ -11,7 +11,7 @@ use crate::disk::fsck::RepairStrategy; use crate::disk::main::DEFAULT_PASSWORD; use crate::disk::REPAIR_DISK_PATH; use crate::firmware::{check_for_firmware_update, update_firmware}; -use crate::init::{InitPhases, InitResult, STANDBY_MODE_PATH}; +use crate::init::{InitPhases, STANDBY_MODE_PATH}; use crate::net::web_server::{UpgradableListener, WebServer}; use crate::prelude::*; use crate::progress::FullProgressTracker; @@ -188,14 +188,14 @@ async fn setup_or_init( })); } - let InitResult { net_ctrl } = + let init_result = crate::init::init(&server.acceptor_setter(), config, init_phases).await?; let rpc_ctx = RpcContext::init( &server.acceptor_setter(), config, disk_guid, - Some(net_ctrl), + Some(init_result), rpc_ctx_phases, ) .await?; diff --git a/core/startos/src/context/config.rs b/core/startos/src/context/config.rs index 3f631c1e4..4a0925d81 100644 --- a/core/startos/src/context/config.rs +++ b/core/startos/src/context/config.rs @@ -108,8 +108,6 @@ pub struct ServerConfig { #[arg(long)] pub tor_socks: Option, #[arg(long)] - pub dns_bind: Option>, - #[arg(long)] pub revision_cache_size: Option, #[arg(long)] pub disable_encryption: Option, @@ -125,7 +123,6 @@ impl ContextConfig for ServerConfig { self.os_partitions = self.os_partitions.take().or(other.os_partitions); self.tor_control = self.tor_control.take().or(other.tor_control); self.tor_socks = self.tor_socks.take().or(other.tor_socks); - self.dns_bind = self.dns_bind.take().or(other.dns_bind); self.revision_cache_size = self .revision_cache_size .take() diff --git a/core/startos/src/context/rpc.rs b/core/startos/src/context/rpc.rs index a00b9d681..1eca857f4 100644 --- a/core/startos/src/context/rpc.rs +++ b/core/startos/src/context/rpc.rs @@ -26,9 +26,9 @@ use crate::auth::Sessions; use crate::context::config::ServerConfig; use crate::db::model::Database; use crate::disk::OsPartitionInfo; -use crate::init::check_time_is_synchronized; +use crate::init::{check_time_is_synchronized, InitResult}; use crate::lxc::{ContainerId, LxcContainer, LxcManager}; -use crate::net::net_controller::{NetController, PreInitNetController}; +use crate::net::net_controller::{NetController, NetService}; use crate::net::utils::{find_eth_iface, find_wifi_iface}; use crate::net::web_server::{UpgradableListener, WebServerAcceptorSetter}; use crate::net::wifi::WpaCli; @@ -53,6 +53,7 @@ pub struct RpcContextSeed { pub sync_db: watch::Sender, pub account: RwLock, pub net_controller: Arc, + pub os_net_service: NetService, pub s9pk_arch: Option<&'static str>, pub services: ServiceMap, pub metrics_cache: RwLock>, @@ -119,7 +120,7 @@ impl RpcContext { webserver: &WebServerAcceptorSetter, config: &ServerConfig, disk_guid: Arc, - net_ctrl: Option, + init_result: Option, InitRpcContextPhases { mut load_db, mut init_net_ctrl, @@ -133,7 +134,7 @@ impl RpcContext { let (shutdown, _) = tokio::sync::broadcast::channel(1); load_db.start(); - let db = if let Some(net_ctrl) = &net_ctrl { + let db = if let Some(InitResult { net_ctrl, .. }) = &init_result { net_ctrl.db.clone() } else { TypedPatchDb::::load(config.db().await?).await? @@ -144,31 +145,28 @@ impl RpcContext { tracing::info!("Opened PatchDB"); init_net_ctrl.start(); - let net_controller = Arc::new( - NetController::init( - if let Some(net_ctrl) = net_ctrl { - net_ctrl - } else { - let net_ctrl = PreInitNetController::init( - db.clone(), - config - .tor_control - .unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))), - tor_proxy, - &account.hostname, - account.tor_key.clone(), - ) - .await?; - webserver.try_upgrade(|a| net_ctrl.net_iface.upgrade_listener(a))?; - net_ctrl - }, - config - .dns_bind - .as_deref() - .unwrap_or(&[SocketAddr::from(([127, 0, 0, 1], 53))]), - ) - .await?, - ); + let (net_controller, os_net_service) = if let Some(InitResult { + net_ctrl, + os_net_service, + }) = init_result + { + (net_ctrl, os_net_service) + } else { + let net_ctrl = Arc::new( + NetController::init( + db.clone(), + config + .tor_control + .unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))), + tor_proxy, + &account.hostname, + ) + .await?, + ); + webserver.try_upgrade(|a| net_ctrl.net_iface.upgrade_listener(a))?; + let os_net_service = net_ctrl.os_bindings().await?; + (net_ctrl, os_net_service) + }; init_net_ctrl.complete(); tracing::info!("Initialized Net Controller"); @@ -230,6 +228,7 @@ impl RpcContext { db, account: RwLock::new(account), net_controller, + os_net_service, s9pk_arch: if config.multi_arch_s9pks.unwrap_or(false) { None } else { diff --git a/core/startos/src/context/setup.rs b/core/startos/src/context/setup.rs index 5c2bf8bfc..b8e4ee968 100644 --- a/core/startos/src/context/setup.rs +++ b/core/startos/src/context/setup.rs @@ -40,7 +40,7 @@ lazy_static::lazy_static! { #[serde(rename_all = "camelCase")] #[ts(export)] pub struct SetupResult { - pub tor_address: String, + pub tor_addresses: Vec, #[ts(type = "string")] pub hostname: Hostname, #[ts(type = "string")] @@ -51,7 +51,11 @@ impl TryFrom<&AccountInfo> for SetupResult { type Error = Error; fn try_from(value: &AccountInfo) -> Result { Ok(Self { - tor_address: format!("https://{}", value.tor_key.public().get_onion_address()), + tor_addresses: value + .tor_keys + .iter() + .map(|tor_key| format!("https://{}", tor_key.public().get_onion_address())) + .collect(), hostname: value.hostname.clone(), lan_address: value.hostname.lan_address(), root_ca: String::from_utf8(value.root_ca_cert.to_pem()?)?, diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index 90df469ba..bb92bbaf9 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -10,19 +10,22 @@ use itertools::Itertools; use models::PackageId; use openssl::hash::MessageDigest; use patch_db::{HasModel, Value}; -use reqwest::Url; use serde::{Deserialize, Serialize}; -use torut::onion::OnionAddressV3; use ts_rs::TS; use crate::account::AccountInfo; use crate::db::model::package::AllPackageData; use crate::net::acme::AcmeProvider; +use crate::net::host::address::DomainConfig; +use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo}; +use crate::net::host::Host; +use crate::net::vhost::AlpnInfo; use crate::prelude::*; use crate::progress::FullProgress; use crate::system::SmtpValue; use crate::util::cpupower::Governor; use crate::util::lshw::LshwDevice; +use crate::util::serde::MaybeUtf8String; use crate::version::{Current, VersionT}; use crate::{ARCH, PLATFORM}; @@ -38,7 +41,6 @@ pub struct Public { } impl Public { pub fn init(account: &AccountInfo) -> Result { - let lan_address = account.hostname.lan_address().parse().unwrap(); Ok(Self { server_info: ServerInfo { arch: get_arch(), @@ -46,14 +48,42 @@ impl Public { id: account.server_id.clone(), version: Current::default().semver(), hostname: account.hostname.no_dot_host_name(), + host: Host { + bindings: [( + 80, + BindInfo { + enabled: false, + options: BindOptions { + preferred_external_port: 80, + add_ssl: Some(AddSslOptions { + preferred_external_port: 443, + alpn: Some(AlpnInfo::Specified(vec![ + MaybeUtf8String("http/1.1".into()), + MaybeUtf8String("h2".into()), + ])), + }), + secure: None, + }, + net: NetInfo { + assigned_port: None, + assigned_ssl_port: Some(443), + public: false, + }, + }, + )] + .into_iter() + .collect(), + onions: account + .tor_keys + .iter() + .map(|k| k.public().get_onion_address()) + .collect(), + domains: BTreeMap::new(), + hostname_info: BTreeMap::new(), + }, last_backup: None, package_version_compat: Current::default().compat().clone(), post_init_migration_todos: BTreeSet::new(), - lan_address, - onion_address: account.tor_key.public().get_onion_address(), - tor_address: format!("https://{}", account.tor_key.public().get_onion_address()) - .parse() - .unwrap(), network_interfaces: BTreeMap::new(), acme: BTreeMap::new(), status_info: ServerStatus { @@ -115,6 +145,7 @@ pub struct ServerInfo { pub id: String, #[ts(type = "string")] pub hostname: InternedString, + pub host: Host, #[ts(type = "string")] pub version: Version, #[ts(type = "string")] @@ -123,13 +154,6 @@ pub struct ServerInfo { pub post_init_migration_todos: BTreeSet, #[ts(type = "string | null")] pub last_backup: Option>, - #[ts(type = "string")] - pub lan_address: Url, - #[ts(type = "string")] - pub onion_address: OnionAddressV3, - /// for backwards compatibility - #[ts(type = "string")] - pub tor_address: Url, #[ts(as = "BTreeMap::")] #[serde(default)] pub network_interfaces: BTreeMap, diff --git a/core/startos/src/init.rs b/core/startos/src/init.rs index 21d23ab5a..b68596a12 100644 --- a/core/startos/src/init.rs +++ b/core/startos/src/init.rs @@ -3,6 +3,7 @@ use std::io::Cursor; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::os::unix::fs::PermissionsExt; use std::path::Path; +use std::sync::Arc; use std::time::{Duration, SystemTime}; use axum::extract::ws::{self}; @@ -25,7 +26,8 @@ use crate::db::model::public::ServerStatus; use crate::db::model::Database; use crate::disk::mount::util::unmount; use crate::middleware::auth::LOCAL_AUTH_COOKIE_PATH; -use crate::net::net_controller::PreInitNetController; +use crate::net::net_controller::{NetController, NetService}; +use crate::net::utils::find_wifi_iface; use crate::net::web_server::{UpgradableListener, WebServerAcceptorSetter}; use crate::prelude::*; use crate::progress::{ @@ -197,7 +199,8 @@ pub async fn init_postgres(datadir: impl AsRef) -> Result<(), Error> { } pub struct InitResult { - pub net_ctrl: PreInitNetController, + pub net_ctrl: Arc, + pub os_net_service: NetService, } pub struct InitPhases { @@ -347,19 +350,21 @@ pub async fn init( let account = AccountInfo::load(&peek)?; start_net.start(); - let net_ctrl = PreInitNetController::init( - db.clone(), - cfg.tor_control - .unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))), - cfg.tor_socks.unwrap_or(SocketAddr::V4(SocketAddrV4::new( - Ipv4Addr::new(127, 0, 0, 1), - 9050, - ))), - &account.hostname, - account.tor_key, - ) - .await?; + let net_ctrl = Arc::new( + NetController::init( + db.clone(), + cfg.tor_control + .unwrap_or(SocketAddr::from(([127, 0, 0, 1], 9051))), + cfg.tor_socks.unwrap_or(SocketAddr::V4(SocketAddrV4::new( + Ipv4Addr::new(127, 0, 0, 1), + 9050, + ))), + &account.hostname, + ) + .await?, + ); webserver.try_upgrade(|a| net_ctrl.net_iface.upgrade_listener(a))?; + let os_net_service = net_ctrl.os_bindings().await?; start_net.complete(); mount_logs.start(); @@ -394,8 +399,6 @@ pub async fn init( mount_logs.complete(); tracing::info!("Mounted Logs"); - let mut server_info = peek.as_public().as_server_info().de()?; - load_ca_cert.start(); // write to ca cert store tokio::fs::write( @@ -423,7 +426,15 @@ pub async fn init( load_ca_cert.complete(); load_wifi.start(); - crate::net::wifi::synchronize_network_manager(MAIN_DATA, &mut server_info.wifi).await?; + let wifi_interface = find_wifi_iface().await?; + let wifi = db + .mutate(|db| { + let wifi = db.as_public_mut().as_server_info_mut().as_wifi_mut(); + wifi.as_interface_mut().ser(&wifi_interface)?; + wifi.de() + }) + .await?; + crate::net::wifi::synchronize_network_manager(MAIN_DATA, &wifi).await?; load_wifi.complete(); tracing::info!("Synchronized WiFi"); @@ -448,8 +459,10 @@ pub async fn init( crate::disk::mount::util::bind(&tmp_docker, CONTAINER_DATADIR, false).await?; init_tmp.complete(); + let server_info = db.peek().await.into_public().into_server_info(); set_governor.start(); - let governor = if let Some(governor) = &server_info.governor { + let selected_governor = server_info.as_governor().de()?; + let governor = if let Some(governor) = &selected_governor { if cpupower::get_available_governors() .await? .contains(governor) @@ -470,11 +483,11 @@ pub async fn init( set_governor.complete(); sync_clock.start(); - server_info.ntp_synced = false; + let mut ntp_synced = false; let mut not_made_progress = 0u32; for _ in 0..1800 { if check_time_is_synchronized().await? { - server_info.ntp_synced = true; + ntp_synced = true; break; } let t = SystemTime::now(); @@ -491,7 +504,7 @@ pub async fn init( break; } } - if !server_info.ntp_synced { + if !ntp_synced { tracing::warn!("Timed out waiting for system time to synchronize"); } else { tracing::info!("Syncronized system clock"); @@ -499,15 +512,16 @@ pub async fn init( sync_clock.complete(); enable_zram.start(); - if server_info.zram { - crate::system::enable_zram().await? + if server_info.as_zram().de()? { + crate::system::enable_zram().await?; + tracing::info!("Enabled ZRAM"); } enable_zram.complete(); update_server_info.start(); - server_info.ram = get_mem_info().await?.total.0 as u64 * 1024 * 1024; - server_info.devices = lshw().await?; - server_info.status_info = ServerStatus { + let ram = get_mem_info().await?.total.0 as u64 * 1024 * 1024; + let devices = lshw().await?; + let status_info = ServerStatus { updated: false, update_progress: None, backup_progress: None, @@ -515,10 +529,15 @@ pub async fn init( restarting: false, }; db.mutate(|v| { - v.as_public_mut().as_server_info_mut().ser(&server_info)?; + let server_info = v.as_public_mut().as_server_info_mut(); + server_info.as_ntp_synced_mut().ser(&ntp_synced)?; + server_info.as_ram_mut().ser(&ram)?; + server_info.as_devices_mut().ser(&devices)?; + server_info.as_status_info_mut().ser(&status_info)?; Ok(()) }) .await?; + tracing::info!("Updated server info"); update_server_info.complete(); launch_service_network.start(); @@ -527,6 +546,7 @@ pub async fn init( .arg("lxc-net.service") .invoke(ErrorKind::Lxc) .await?; + tracing::info!("Launched service intranet"); launch_service_network.complete(); validate_db.start(); @@ -535,6 +555,7 @@ pub async fn init( d.ser(&model) }) .await?; + tracing::info!("Validated database"); validate_db.complete(); if let Some(progress) = postinit { @@ -543,7 +564,10 @@ pub async fn init( tracing::info!("System initialized."); - Ok(InitResult { net_ctrl }) + Ok(InitResult { + net_ctrl, + os_net_service, + }) } pub fn init_api() -> ParentHandler { diff --git a/core/startos/src/lib.rs b/core/startos/src/lib.rs index ad214da34..bcdcb7f91 100644 --- a/core/startos/src/lib.rs +++ b/core/startos/src/lib.rs @@ -87,6 +87,7 @@ use crate::context::{ CliContext, DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext, }; use crate::disk::fsck::RequiresReboot; +use crate::net::net; use crate::registry::context::{RegistryContext, RegistryUrlParams}; use crate::util::serde::HandlerExtSerde; @@ -313,7 +314,7 @@ pub fn server() -> ParentHandler { .no_display() .with_about("Remove system smtp server and credentials") .with_call_remote::() - ) + ).subcommand("host", net::host::server_host_api::().with_about("Commands for modifying the host for the system ui")) } pub fn package() -> ParentHandler { @@ -427,7 +428,7 @@ pub fn package() -> ParentHandler { .subcommand("attach", from_fn_async(service::cli_attach).no_display()) .subcommand( "host", - net::host::host::().with_about("Manage network hosts for a package"), + net::host::host_api::().with_about("Manage network hosts for a package"), ) } diff --git a/core/startos/src/middleware/cors.rs b/core/startos/src/middleware/cors.rs index a8c406a8a..60e8247ea 100644 --- a/core/startos/src/middleware/cors.rs +++ b/core/startos/src/middleware/cors.rs @@ -1,6 +1,7 @@ +use axum::body::Body; use axum::extract::Request; use axum::response::Response; -use http::{HeaderMap, HeaderValue}; +use http::{HeaderMap, HeaderValue, Method}; use rpc_toolkit::{Empty, Middleware}; #[derive(Clone)] @@ -52,6 +53,13 @@ impl Middleware for Cors { request: &mut Request, ) -> Result<(), Response> { self.get_cors_headers(request); + if request.method() == Method::OPTIONS { + let mut response = Response::new(Body::empty()); + response + .headers_mut() + .extend(std::mem::take(&mut self.headers)); + return Err(response); + } Ok(()) } async fn process_http_response(&mut self, _: &Context, response: &mut Response) { diff --git a/core/startos/src/net/acme.rs b/core/startos/src/net/acme.rs index 5d8da41f1..9ef2af1f7 100644 --- a/core/startos/src/net/acme.rs +++ b/core/startos/src/net/acme.rs @@ -173,16 +173,26 @@ impl<'a> async_acme::cache::AcmeCache for AcmeCertCache<'a> { } pub fn acme() -> ParentHandler { - ParentHandler::new().subcommand( - "init", - from_fn_async(init) - .no_display() - .with_about("Setup ACME certificate acquisition") - .with_call_remote::(), - ) + ParentHandler::new() + .subcommand( + "init", + from_fn_async(init) + .with_metadata("sync_db", Value::Bool(true)) + .no_display() + .with_about("Setup ACME certificate acquisition") + .with_call_remote::(), + ) + .subcommand( + "remove", + from_fn_async(remove) + .with_metadata("sync_db", Value::Bool(true)) + .no_display() + .with_about("Setup ACME certificate acquisition") + .with_call_remote::(), + ) } -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, TS)] #[ts(type = "string")] pub struct AcmeProvider(pub Url); impl FromStr for AcmeProvider { @@ -193,9 +203,31 @@ impl FromStr for AcmeProvider { "letsencrypt-staging" => async_acme::acme::LETS_ENCRYPT_STAGING_DIRECTORY.parse(), s => s.parse(), } + .map(|mut u: Url| { + let path = u + .path_segments() + .into_iter() + .flatten() + .filter(|p| !p.is_empty()) + .map(|p| p.to_owned()) + .collect::>(); + if let Ok(mut path_mut) = u.path_segments_mut() { + path_mut.clear(); + path_mut.extend(path); + } + u + }) .map(Self) } } +impl<'de> Deserialize<'de> for AcmeProvider { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + crate::util::serde::deserialize_from_str(deserializer) + } +} impl AsRef for AcmeProvider { fn as_ref(&self) -> &str { self.0.as_str() @@ -230,3 +262,24 @@ pub async fn init( .await?; Ok(()) } + +#[derive(Deserialize, Serialize, Parser)] +pub struct RemoveAcmeParams { + #[arg(long)] + pub provider: AcmeProvider, +} + +pub async fn remove( + ctx: RpcContext, + RemoveAcmeParams { provider }: RemoveAcmeParams, +) -> Result<(), Error> { + ctx.db + .mutate(|db| { + db.as_public_mut() + .as_server_info_mut() + .as_acme_mut() + .remove(&provider) + }) + .await?; + Ok(()) +} diff --git a/core/startos/src/net/dns.rs b/core/startos/src/net/dns.rs index 016e5de9f..d68a971f1 100644 --- a/core/startos/src/net/dns.rs +++ b/core/startos/src/net/dns.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; use std::collections::BTreeMap; -use std::net::{Ipv4Addr, SocketAddr}; +use std::net::Ipv4Addr; use std::sync::{Arc, Weak}; use std::time::Duration; @@ -19,6 +19,7 @@ use trust_dns_server::server::{Request, RequestHandler, ResponseHandler, Respons use trust_dns_server::ServerFuture; use crate::net::forward::START9_BRIDGE_IFACE; +use crate::util::sync::Watch; use crate::util::Invoke; use crate::{Error, ErrorKind, ResultExt}; @@ -140,38 +141,46 @@ impl RequestHandler for Resolver { impl DnsController { #[instrument(skip_all)] - pub async fn init(bind: &[SocketAddr]) -> Result { + pub async fn init(mut lxcbr_status: Watch) -> Result { let services = Arc::new(RwLock::new(BTreeMap::new())); let mut server = ServerFuture::new(Resolver { services: services.clone(), }); - server.register_listener( - TcpListener::bind(bind) - .await - .with_kind(ErrorKind::Network)?, - Duration::from_secs(30), - ); - server.register_socket(UdpSocket::bind(bind).await.with_kind(ErrorKind::Network)?); - Command::new("resolvectl") - .arg("dns") - .arg(START9_BRIDGE_IFACE) - .arg("127.0.0.1") - .invoke(ErrorKind::Network) - .await?; - Command::new("resolvectl") - .arg("domain") - .arg(START9_BRIDGE_IFACE) - .arg("embassy") - .invoke(ErrorKind::Network) - .await?; + let dns_server = tokio::spawn(async move { + server.register_listener( + TcpListener::bind((Ipv4Addr::LOCALHOST, 53)) + .await + .with_kind(ErrorKind::Network)?, + Duration::from_secs(30), + ); + server.register_socket( + UdpSocket::bind((Ipv4Addr::LOCALHOST, 53)) + .await + .with_kind(ErrorKind::Network)?, + ); + + lxcbr_status.wait_for(|a| *a).await; + + Command::new("resolvectl") + .arg("dns") + .arg(START9_BRIDGE_IFACE) + .arg("127.0.0.1") + .invoke(ErrorKind::Network) + .await?; + Command::new("resolvectl") + .arg("domain") + .arg(START9_BRIDGE_IFACE) + .arg("embassy") + .invoke(ErrorKind::Network) + .await?; - let dns_server = tokio::spawn( server .block_until_done() - .map_err(|e| Error::new(e, ErrorKind::Network)), - ) + .await + .map_err(|e| Error::new(e, ErrorKind::Network)) + }) .into(); Ok(Self { diff --git a/core/startos/src/net/host/address.rs b/core/startos/src/net/host/address.rs index fa41824a5..b75734a13 100644 --- a/core/startos/src/net/host/address.rs +++ b/core/startos/src/net/host/address.rs @@ -1,13 +1,16 @@ +use std::collections::BTreeSet; + use clap::Parser; use imbl_value::InternedString; -use models::{HostId, PackageId}; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; use torut::onion::OnionAddressV3; use ts_rs::TS; use crate::context::{CliContext, RpcContext}; +use crate::db::model::DatabaseModel; use crate::net::acme::AcmeProvider; +use crate::net::host::{all_hosts, HostApiKind}; use crate::prelude::*; use crate::util::serde::{display_serializable, HandlerExtSerde}; @@ -35,19 +38,51 @@ pub struct DomainConfig { pub acme: Option, } -#[derive(Deserialize, Serialize, Parser)] -pub struct AddressApiParams { - host: HostId, +fn check_duplicates(db: &DatabaseModel) -> Result<(), Error> { + let mut onions = BTreeSet::::new(); + let mut domains = BTreeSet::::new(); + let mut check_onion = |onion: OnionAddressV3| { + if onions.contains(&onion) { + return Err(Error::new( + eyre!("onion address {onion} is already in use"), + ErrorKind::InvalidRequest, + )); + } + onions.insert(onion); + Ok(()) + }; + let mut check_domain = |domain: InternedString| { + if domains.contains(&domain) { + return Err(Error::new( + eyre!("domain {domain} is already in use"), + ErrorKind::InvalidRequest, + )); + } + domains.insert(domain); + Ok(()) + }; + for host in all_hosts(db) { + let host = host?; + for onion in host.as_onions().de()? { + check_onion(onion)?; + } + for domain in host.as_domains().keys()? { + check_domain(domain)?; + } + } + Ok(()) } -pub fn address() -> ParentHandler { - ParentHandler::::new() +pub fn address_api( +) -> ParentHandler { + ParentHandler::::new() .subcommand( "domain", - ParentHandler::::new() + ParentHandler::::new() .subcommand( "add", - from_fn_async(add_domain) + from_fn_async(add_domain::) + .with_metadata("sync_db", Value::Bool(true)) .with_inherited(|_, a| a) .no_display() .with_about("Add an address to this host") @@ -55,20 +90,22 @@ pub fn address() -> ParentHandler { ) .subcommand( "remove", - from_fn_async(remove_domain) + from_fn_async(remove_domain::) + .with_metadata("sync_db", Value::Bool(true)) .with_inherited(|_, a| a) .no_display() .with_about("Remove an address from this host") .with_call_remote::(), ) - .with_inherited(|AddressApiParams { host }, package| (package, host)), + .with_inherited(Kind::inheritance), ) .subcommand( "onion", - ParentHandler::::new() + ParentHandler::::new() .subcommand( "add", - from_fn_async(add_onion) + from_fn_async(add_onion::) + .with_metadata("sync_db", Value::Bool(true)) .with_inherited(|_, a| a) .no_display() .with_about("Add an address to this host") @@ -76,18 +113,19 @@ pub fn address() -> ParentHandler { ) .subcommand( "remove", - from_fn_async(remove_onion) + from_fn_async(remove_onion::) + .with_metadata("sync_db", Value::Bool(true)) .with_inherited(|_, a| a) .no_display() .with_about("Remove an address from this host") .with_call_remote::(), ) - .with_inherited(|AddressApiParams { host }, package| (package, host)), + .with_inherited(Kind::inheritance), ) .subcommand( "list", - from_fn_async(list_addresses) - .with_inherited(|AddressApiParams { host }, package| (package, host)) + from_fn_async(list_addresses::) + .with_inherited(Kind::inheritance) .with_display_serializable() .with_custom_display_fn(|HandlerArgs { params, .. }, res| { use prettytable::*; @@ -136,14 +174,14 @@ pub struct AddDomainParams { pub acme: Option, } -pub async fn add_domain( +pub async fn add_domain( ctx: RpcContext, AddDomainParams { domain, private, acme, }: AddDomainParams, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result<(), Error> { ctx.db .mutate(|db| { @@ -153,13 +191,7 @@ pub async fn add_domain( } } - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? + Kind::host_for(&inheritance, db)? .as_domains_mut() .insert( &domain, @@ -167,12 +199,11 @@ pub async fn add_domain( public: !private, acme, }, - ) + )?; + check_duplicates(db) }) .await?; - let service = ctx.services.get(&package).await; - let service_ref = service.as_ref().or_not_found(&package)?; - service_ref.update_host(host).await?; + Kind::sync_host(&ctx, inheritance).await?; Ok(()) } @@ -182,27 +213,19 @@ pub struct RemoveDomainParams { pub domain: InternedString, } -pub async fn remove_domain( +pub async fn remove_domain( ctx: RpcContext, RemoveDomainParams { domain }: RemoveDomainParams, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result<(), Error> { ctx.db .mutate(|db| { - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? + Kind::host_for(&inheritance, db)? .as_domains_mut() .remove(&domain) }) .await?; - let service = ctx.services.get(&package).await; - let service_ref = service.as_ref().or_not_found(&package)?; - service_ref.update_host(host).await?; + Kind::sync_host(&ctx, inheritance).await?; Ok(()) } @@ -212,10 +235,10 @@ pub struct OnionParams { pub onion: String, } -pub async fn add_onion( +pub async fn add_onion( ctx: RpcContext, OnionParams { onion }: OnionParams, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result<(), Error> { let onion = onion .strip_suffix(".onion") @@ -230,28 +253,22 @@ pub async fn add_onion( .mutate(|db| { db.as_private().as_key_store().as_onion().get_key(&onion)?; - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? + Kind::host_for(&inheritance, db)? .as_onions_mut() - .mutate(|a| Ok(a.insert(onion))) + .mutate(|a| Ok(a.insert(onion)))?; + check_duplicates(db) }) .await?; - let service = ctx.services.get(&package).await; - let service_ref = service.as_ref().or_not_found(&package)?; - service_ref.update_host(host).await?; + + Kind::sync_host(&ctx, inheritance).await?; Ok(()) } -pub async fn remove_onion( +pub async fn remove_onion( ctx: RpcContext, OnionParams { onion }: OnionParams, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result<(), Error> { let onion = onion .strip_suffix(".onion") @@ -264,40 +281,23 @@ pub async fn remove_onion( .parse::()?; ctx.db .mutate(|db| { - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? + Kind::host_for(&inheritance, db)? .as_onions_mut() .mutate(|a| Ok(a.remove(&onion))) }) .await?; - let service = ctx.services.get(&package).await; - let service_ref = service.as_ref().or_not_found(&package)?; - service_ref.update_host(host).await?; + + Kind::sync_host(&ctx, inheritance).await?; Ok(()) } -pub async fn list_addresses( +pub async fn list_addresses( ctx: RpcContext, _: Empty, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result, Error> { - Ok(ctx - .db - .peek() - .await - .into_public() - .into_package_data() - .into_idx(&package) - .or_not_found(&package)? - .into_hosts() - .into_idx(&host) - .or_not_found(&host)? + Ok(Kind::host_for(&inheritance, &mut ctx.db.peek().await)? .de()? .addresses() .collect()) diff --git a/core/startos/src/net/host/binding.rs b/core/startos/src/net/host/binding.rs index 08f9f68c4..5b726a82d 100644 --- a/core/startos/src/net/host/binding.rs +++ b/core/startos/src/net/host/binding.rs @@ -3,13 +3,14 @@ use std::str::FromStr; use clap::builder::ValueParserFactory; use clap::Parser; -use models::{FromStrParser, HostId, PackageId}; +use models::{FromStrParser, HostId}; use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; use ts_rs::TS; use crate::context::{CliContext, RpcContext}; use crate::net::forward::AvailablePorts; +use crate::net::host::HostApiKind; use crate::net::vhost::AlpnInfo; use crate::prelude::*; use crate::util::serde::{display_serializable, HandlerExtSerde}; @@ -146,17 +147,13 @@ pub struct AddSslOptions { pub alpn: Option, } -#[derive(Deserialize, Serialize, Parser)] -pub struct BindingApiParams { - host: HostId, -} - -pub fn binding() -> ParentHandler { - ParentHandler::::new() +pub fn binding( +) -> ParentHandler { + ParentHandler::::new() .subcommand( "list", - from_fn_async(list_bindings) - .with_inherited(|BindingApiParams { host }, package| (package, host)) + from_fn_async(list_bindings::) + .with_inherited(Kind::inheritance) .with_display_serializable() .with_custom_display_fn(|HandlerArgs { params, .. }, res| { use prettytable::*; @@ -194,30 +191,22 @@ pub fn binding() -> ParentHandler { ) .subcommand( "set-public", - from_fn_async(set_public) - .with_inherited(|BindingApiParams { host }, package| (package, host)) + from_fn_async(set_public::) + .with_metadata("sync_db", Value::Bool(true)) + .with_inherited(Kind::inheritance) .no_display() .with_about("Add an binding to this host") .with_call_remote::(), ) } -pub async fn list_bindings( +pub async fn list_bindings( ctx: RpcContext, _: Empty, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result, Error> { - ctx.db - .peek() - .await - .into_public() - .into_package_data() - .into_idx(&package) - .or_not_found(&package)? - .into_hosts() - .into_idx(&host) - .or_not_found(&host)? - .into_bindings() + Kind::host_for(&inheritance, &mut ctx.db.peek().await)? + .as_bindings() .de() } @@ -230,23 +219,17 @@ pub struct BindingSetPublicParams { public: Option, } -pub async fn set_public( +pub async fn set_public( ctx: RpcContext, BindingSetPublicParams { internal_port, public, }: BindingSetPublicParams, - (package, host): (PackageId, HostId), + inheritance: Kind::Inheritance, ) -> Result<(), Error> { ctx.db .mutate(|db| { - db.as_public_mut() - .as_package_data_mut() - .as_idx_mut(&package) - .or_not_found(&package)? - .as_hosts_mut() - .as_idx_mut(&host) - .or_not_found(&host)? + Kind::host_for(&inheritance, db)? .as_bindings_mut() .mutate(|b| { b.get_mut(&internal_port) @@ -257,11 +240,5 @@ pub async fn set_public( }) }) .await?; - ctx.services - .get(&package) - .await - .as_ref() - .or_not_found(&package)? - .update_host(host) - .await + Kind::sync_host(&ctx, inheritance).await } diff --git a/core/startos/src/net/host/mod.rs b/core/startos/src/net/host/mod.rs index 9f4194866..df209cef5 100644 --- a/core/startos/src/net/host/mod.rs +++ b/core/startos/src/net/host/mod.rs @@ -1,9 +1,12 @@ use std::collections::{BTreeMap, BTreeSet}; +use std::future::Future; +use std::panic::RefUnwindSafe; use clap::Parser; use imbl_value::InternedString; +use itertools::Itertools; use models::{HostId, PackageId}; -use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler}; +use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, OrEmpty, ParentHandler}; use serde::{Deserialize, Serialize}; use torut::onion::OnionAddressV3; use ts_rs::TS; @@ -11,7 +14,7 @@ use ts_rs::TS; use crate::context::RpcContext; use crate::db::model::DatabaseModel; use crate::net::forward::AvailablePorts; -use crate::net::host::address::{address, DomainConfig, HostAddress}; +use crate::net::host::address::{address_api, DomainConfig, HostAddress}; use crate::net::host::binding::{binding, BindInfo, BindOptions}; use crate::net::service_interface::HostnameInfo; use crate::prelude::*; @@ -19,12 +22,11 @@ use crate::prelude::*; pub mod address; pub mod binding; -#[derive(Debug, Deserialize, Serialize, HasModel, TS)] +#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)] #[serde(rename_all = "camelCase")] #[model = "Model"] #[ts(export)] pub struct Host { - pub kind: HostKind, pub bindings: BTreeMap, #[ts(type = "string[]")] pub onions: BTreeSet, @@ -39,14 +41,8 @@ impl AsRef for Host { } } impl Host { - pub fn new(kind: HostKind) -> Self { - Self { - kind, - bindings: BTreeMap::new(), - onions: BTreeSet::new(), - domains: BTreeMap::new(), - hostname_info: BTreeMap::new(), - } + pub fn new() -> Self { + Self::default() } pub fn addresses<'a>(&'a self) -> impl Iterator + 'a { self.onions @@ -67,15 +63,6 @@ impl Host { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] -#[serde(rename_all = "camelCase")] -#[ts(export)] -pub enum HostKind { - Multi, - // Single, - // Static, -} - #[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)] #[model = "Model"] #[ts(export)] @@ -94,10 +81,12 @@ impl Map for Hosts { pub fn host_for<'a>( db: &'a mut DatabaseModel, - package_id: &PackageId, + package_id: Option<&PackageId>, host_id: &HostId, - host_kind: HostKind, ) -> Result<&'a mut Model, Error> { + let Some(package_id) = package_id else { + return Ok(db.as_public_mut().as_server_info_mut().as_host_mut()); + }; fn host_info<'a>( db: &'a mut DatabaseModel, package_id: &PackageId, @@ -121,7 +110,7 @@ pub fn host_for<'a>( None }; host_info(db, package_id)?.upsert(host_id, || { - let mut h = Host::new(host_kind); + let mut h = Host::new(); h.onions.insert( tor_key .or_not_found("generated tor key")? @@ -132,12 +121,20 @@ pub fn host_for<'a>( }) } +pub fn all_hosts(db: &DatabaseModel) -> impl Iterator, Error>> { + [Ok(db.as_public().as_server_info().as_host())] + .into_iter() + .chain( + [db.as_public().as_package_data().as_entries()] + .into_iter() + .flatten_ok() + .map(|entry| entry.and_then(|(_, v)| v.as_hosts().as_entries())) + .flatten_ok() + .map_ok(|(_, v)| v), + ) +} + impl Model { - pub fn set_kind(&mut self, kind: HostKind) -> Result<(), Error> { - match (self.as_kind().de()?, kind) { - (HostKind::Multi, HostKind::Multi) => Ok(()), - } - } pub fn add_binding( &mut self, available_ports: &mut AvailablePorts, @@ -157,16 +154,78 @@ impl Model { } #[derive(Deserialize, Serialize, Parser)] -pub struct HostParams { +pub struct RequiresPackageId { package: PackageId, } -pub fn host() -> ParentHandler { - ParentHandler::::new() +#[derive(Deserialize, Serialize, Parser)] +pub struct RequiresHostId { + host: HostId, +} + +pub trait HostApiKind: 'static { + type Params: Send + Sync + 'static; + type InheritedParams: Send + Sync + 'static; + type Inheritance: RefUnwindSafe + OrEmpty + Send + Sync + 'static; + fn inheritance(params: Self::Params, inherited: Self::InheritedParams) -> Self::Inheritance; + fn host_for<'a>( + inheritance: &Self::Inheritance, + db: &'a mut DatabaseModel, + ) -> Result<&'a mut Model, Error>; + fn sync_host( + ctx: &RpcContext, + inheritance: Self::Inheritance, + ) -> impl Future> + Send; +} +pub struct ForPackage; +impl HostApiKind for ForPackage { + type Params = RequiresHostId; + type InheritedParams = PackageId; + type Inheritance = (PackageId, HostId); + fn inheritance( + RequiresHostId { host }: Self::Params, + package: Self::InheritedParams, + ) -> Self::Inheritance { + (package, host) + } + fn host_for<'a>( + (package, host): &Self::Inheritance, + db: &'a mut DatabaseModel, + ) -> Result<&'a mut Model, Error> { + host_for(db, Some(package), host) + } + async fn sync_host(ctx: &RpcContext, (package, host): Self::Inheritance) -> Result<(), Error> { + let service = ctx.services.get(&package).await; + let service_ref = service.as_ref().or_not_found(&package)?; + service_ref.sync_host(host).await?; + Ok(()) + } +} +pub struct ForServer; +impl HostApiKind for ForServer { + type Params = Empty; + type InheritedParams = Empty; + type Inheritance = Empty; + fn inheritance(_: Self::Params, _: Self::InheritedParams) -> Self::Inheritance { + Empty {} + } + fn host_for<'a>( + _: &Self::Inheritance, + db: &'a mut DatabaseModel, + ) -> Result<&'a mut Model, Error> { + host_for(db, None, &HostId::default()) + } + async fn sync_host(ctx: &RpcContext, _: Self::Inheritance) -> Result<(), Error> { + ctx.os_net_service.sync_host(HostId::default()).await + } +} + +pub fn host_api() -> ParentHandler { + ParentHandler::::new() .subcommand( "list", from_fn_async(list_hosts) - .with_inherited(|HostParams { package }, _| package) + .with_inherited(|RequiresPackageId { package }, _| package) .with_custom_display_fn(|_, ids| { for id in ids { println!("{id}") @@ -177,14 +236,21 @@ pub fn host() -> ParentHandler { ) .subcommand( "address", - address::().with_inherited(|HostParams { package }, _| package), + address_api::() + .with_inherited(|RequiresPackageId { package }, _| package), ) .subcommand( "binding", - binding::().with_inherited(|HostParams { package }, _| package), + binding::().with_inherited(|RequiresPackageId { package }, _| package), ) } +pub fn server_host_api() -> ParentHandler { + ParentHandler::::new() + .subcommand("address", address_api::()) + .subcommand("binding", binding::()) +} + pub async fn list_hosts( ctx: RpcContext, _: Empty, diff --git a/core/startos/src/net/keys.rs b/core/startos/src/net/keys.rs index 866b2ca06..2cfcb025d 100644 --- a/core/startos/src/net/keys.rs +++ b/core/startos/src/net/keys.rs @@ -21,7 +21,9 @@ impl KeyStore { local_certs: CertStore::new(account)?, acme: AcmeCertStore::new(), }; - res.onion.insert(account.tor_key.clone()); + for tor_key in account.tor_keys.iter().cloned() { + res.onion.insert(tor_key); + } Ok(res) } } diff --git a/core/startos/src/net/net_controller.rs b/core/startos/src/net/net_controller.rs index 7ff707fbe..8c3fe6ae1 100644 --- a/core/startos/src/net/net_controller.rs +++ b/core/startos/src/net/net_controller.rs @@ -7,6 +7,8 @@ use imbl::OrdMap; use imbl_value::InternedString; use ipnet::IpNet; use models::{HostId, OptionExt, PackageId}; +use tokio::sync::Mutex; +use tokio::task::JoinHandle; use torut::onion::{OnionAddressV3, TorSecretKeyV3}; use tracing::instrument; @@ -16,8 +18,8 @@ use crate::hostname::Hostname; use crate::net::dns::DnsController; use crate::net::forward::LanPortForwardController; use crate::net::host::address::HostAddress; -use crate::net::host::binding::{BindId, BindOptions}; -use crate::net::host::{host_for, Host, HostKind, Hosts}; +use crate::net::host::binding::{AddSslOptions, BindId, BindOptions}; +use crate::net::host::{host_for, Host, Hosts}; use crate::net::network_interface::NetworkInterfaceController; use crate::net::service_interface::{HostnameInfo, IpHostname, OnionHostname}; use crate::net::tor::TorController; @@ -27,129 +29,44 @@ use crate::prelude::*; use crate::util::serde::MaybeUtf8String; use crate::HOST_IP; -pub struct PreInitNetController { - pub db: TypedPatchDb, - tor: TorController, - vhost: VHostController, - pub net_iface: Arc, - os_bindings: Vec>, - server_hostnames: Vec>, -} -impl PreInitNetController { - #[instrument(skip_all)] - pub async fn init( - db: TypedPatchDb, - tor_control: SocketAddr, - tor_socks: SocketAddr, - hostname: &Hostname, - os_tor_key: TorSecretKeyV3, - ) -> Result { - let net_iface = Arc::new(NetworkInterfaceController::new(db.clone())); - let mut res = Self { - db: db.clone(), - tor: TorController::new(tor_control, tor_socks), - vhost: VHostController::new(db, net_iface.clone()), - net_iface, - os_bindings: Vec::new(), - server_hostnames: Vec::new(), - }; - res.add_os_bindings(hostname, os_tor_key).await?; - Ok(res) - } - - async fn add_os_bindings( - &mut self, - hostname: &Hostname, - tor_key: TorSecretKeyV3, - ) -> Result<(), Error> { - self.server_hostnames = vec![ - // LAN IP - None, - // Internal DNS - Some("embassy".into()), - Some("startos".into()), - // localhost - Some("localhost".into()), - Some(hostname.no_dot_host_name()), - // LAN mDNS - Some(hostname.local_domain_name()), - ]; - - let vhost_target = TargetInfo { - public: false, - acme: None, - addr: ([127, 0, 0, 1], 80).into(), - connect_ssl: Err(AlpnInfo::Specified(vec![ - MaybeUtf8String("http/1.1".into()), - MaybeUtf8String("h2".into()), - ])), - }; - - for hostname in self.server_hostnames.iter().cloned() { - self.os_bindings - .push(self.vhost.add(hostname, 443, vhost_target.clone())?); - } - - // Tor - self.os_bindings.push(self.vhost.add( - Some(InternedString::from_display( - &tor_key.public().get_onion_address(), - )), - 443, - vhost_target, - )?); - self.os_bindings.extend( - self.tor - .add( - tor_key, - vec![ - (80, ([127, 0, 0, 1], 80).into()), // http - (443, ([127, 0, 0, 1], 443).into()), // https - ], - ) - .await?, - ); - - Ok(()) - } -} - pub struct NetController { - db: TypedPatchDb, + pub(crate) db: TypedPatchDb, pub(super) tor: TorController, pub(super) vhost: VHostController, - pub net_iface: Arc, + pub(crate) net_iface: Arc, pub(super) dns: DnsController, pub(super) forward: LanPortForwardController, - pub(super) os_bindings: Vec>, pub(super) server_hostnames: Vec>, } impl NetController { pub async fn init( - PreInitNetController { - db, - tor, - vhost, - net_iface, - os_bindings, - server_hostnames, - }: PreInitNetController, - dns_bind: &[SocketAddr], + db: TypedPatchDb, + tor_control: SocketAddr, + tor_socks: SocketAddr, + hostname: &Hostname, ) -> Result { - let mut res = Self { - db, - tor, - vhost, - dns: DnsController::init(dns_bind).await?, + let net_iface = Arc::new(NetworkInterfaceController::new(db.clone())); + Ok(Self { + db: db.clone(), + tor: TorController::new(tor_control, tor_socks), + vhost: VHostController::new(db, net_iface.clone()), + dns: DnsController::init(net_iface.lxcbr_status()).await?, forward: LanPortForwardController::new(net_iface.subscribe()), net_iface, - os_bindings, - server_hostnames, - }; - res.os_bindings - .push(res.dns.add(None, HOST_IP.into()).await?); - Ok(res) + server_hostnames: vec![ + // LAN IP + None, + // Internal DNS + Some("embassy".into()), + Some("startos".into()), + // localhost + Some("localhost".into()), + Some(hostname.no_dot_host_name()), + // LAN mDNS + Some(hostname.local_domain_name()), + ], + }) } #[instrument(skip_all)] @@ -160,17 +77,48 @@ impl NetController { ) -> Result { let dns = self.dns.add(Some(package.clone()), ip).await?; - let mut res = NetService { - shutdown: false, - id: package, + let res = NetService::new(NetServiceData { + id: Some(package), ip, dns, controller: Arc::downgrade(self), binds: BTreeMap::new(), - }; + })?; res.clear_bindings(Default::default()).await?; Ok(res) } + + pub async fn os_bindings(self: &Arc) -> Result { + let dns = self.dns.add(None, HOST_IP.into()).await?; + + let service = NetService::new(NetServiceData { + id: None, + ip: [127, 0, 0, 1].into(), + dns, + controller: Arc::downgrade(self), + binds: BTreeMap::new(), + })?; + service.clear_bindings(Default::default()).await?; + service + .bind( + HostId::default(), + 80, + BindOptions { + preferred_external_port: 80, + add_ssl: Some(AddSslOptions { + preferred_external_port: 443, + alpn: Some(AlpnInfo::Specified(vec![ + MaybeUtf8String("http/1.1".into()), + MaybeUtf8String("h2".into()), + ])), + }), + secure: None, + }, + ) + .await?; + + Ok(service) + } } #[derive(Default, Debug)] @@ -180,15 +128,14 @@ struct HostBinds { tor: BTreeMap, Vec>)>, } -pub struct NetService { - shutdown: bool, - id: PackageId, +pub struct NetServiceData { + id: Option, ip: Ipv4Addr, dns: Arc<()>, controller: Weak, binds: BTreeMap, } -impl NetService { +impl NetServiceData { fn net_controller(&self) -> Result, Error> { Weak::upgrade(&self.controller).ok_or_else(|| { Error::new( @@ -198,49 +145,54 @@ impl NetService { }) } - pub async fn bind( + async fn clear_bindings( &mut self, - kind: HostKind, - id: HostId, - internal_port: u16, - options: BindOptions, + ctrl: &NetController, + except: BTreeSet, ) -> Result<(), Error> { - crate::dbg!("bind", &kind, &id, internal_port, &options); - let pkg_id = &self.id; - let host = self - .net_controller()? - .db - .mutate(|db| { - let mut ports = db.as_private().as_available_ports().de()?; - let host = host_for(db, pkg_id, &id, kind)?; - host.add_binding(&mut ports, internal_port, options)?; - let host = host.de()?; - db.as_private_mut().as_available_ports_mut().ser(&ports)?; - Ok(host) - }) - .await?; - self.update(id, host).await - } - - pub async fn clear_bindings(&mut self, except: BTreeSet) -> Result<(), Error> { - let pkg_id = &self.id; - let hosts = self - .net_controller()? - .db - .mutate(|db| { - let mut res = Hosts::default(); - for (host_id, host) in db - .as_public_mut() - .as_package_data_mut() - .as_idx_mut(pkg_id) - .or_not_found(pkg_id)? - .as_hosts_mut() - .as_entries_mut()? - { + if let Some(pkg_id) = &self.id { + let hosts = ctrl + .db + .mutate(|db| { + let mut res = Hosts::default(); + for (host_id, host) in db + .as_public_mut() + .as_package_data_mut() + .as_idx_mut(pkg_id) + .or_not_found(pkg_id)? + .as_hosts_mut() + .as_entries_mut()? + { + host.as_bindings_mut().mutate(|b| { + for (internal_port, info) in b { + if !except.contains(&BindId { + id: host_id.clone(), + internal_port: *internal_port, + }) { + info.disable(); + } + } + Ok(()) + })?; + res.0.insert(host_id, host.de()?); + } + Ok(res) + }) + .await?; + let mut errors = ErrorCollection::new(); + for (id, host) in hosts.0 { + errors.handle(self.update(ctrl, id, host).await); + } + errors.into_result() + } else { + let host = ctrl + .db + .mutate(|db| { + let host = db.as_public_mut().as_server_info_mut().as_host_mut(); host.as_bindings_mut().mutate(|b| { for (internal_port, info) in b { if !except.contains(&BindId { - id: host_id.clone(), + id: HostId::default(), internal_port: *internal_port, }) { info.disable(); @@ -248,20 +200,14 @@ impl NetService { } Ok(()) })?; - res.0.insert(host_id, host.de()?); - } - Ok(res) - }) - .await?; - let mut errors = ErrorCollection::new(); - for (id, host) in hosts.0 { - errors.handle(self.update(id, host).await); + host.de() + }) + .await?; + self.update(ctrl, HostId::default(), host).await } - errors.into_result() } - pub async fn update(&mut self, id: HostId, host: Host) -> Result<(), Error> { - let ctrl = self.net_controller()?; + async fn update(&mut self, ctrl: &NetController, id: HostId, host: Host) -> Result<(), Error> { let mut forwards: BTreeMap = BTreeMap::new(); let mut vhosts: BTreeMap<(Option, u16), TargetInfo> = BTreeMap::new(); let mut tor: BTreeMap)> = @@ -630,7 +576,7 @@ impl NetService { ctrl.db .mutate(|db| { - host_for(db, &self.id, &id, host.kind)? + host_for(db, self.id.as_ref(), &id)? .as_hostname_info_mut() .ser(&hostname_info) }) @@ -638,10 +584,129 @@ impl NetService { Ok(()) } + async fn update_all(&mut self) -> Result<(), Error> { + let ctrl = self.net_controller()?; + if let Some(id) = &self.id { + for (host_id, host) in ctrl + .db + .peek() + .await + .as_public() + .as_package_data() + .as_idx(id) + .or_not_found(id)? + .as_hosts() + .as_entries()? + { + self.update(&*ctrl, host_id, host.de()?).await?; + } + } else { + self.update( + &*ctrl, + HostId::default(), + ctrl.db + .peek() + .await + .as_public() + .as_server_info() + .as_host() + .de()?, + ) + .await?; + } + Ok(()) + } +} + +pub struct NetService { + shutdown: bool, + data: Arc>, + sync_task: JoinHandle<()>, +} +impl NetService { + fn dummy() -> Self { + Self { + shutdown: true, + data: Arc::new(Mutex::new(NetServiceData { + id: None, + ip: Ipv4Addr::new(0, 0, 0, 0), + dns: Default::default(), + controller: Default::default(), + binds: BTreeMap::new(), + })), + sync_task: tokio::spawn(futures::future::ready(())), + } + } + + fn new(data: NetServiceData) -> Result { + let mut ip_info = data.net_controller()?.net_iface.subscribe(); + let data = Arc::new(Mutex::new(data)); + let thread_data = data.clone(); + let sync_task = tokio::spawn(async move { + loop { + if let Err(e) = thread_data.lock().await.update_all().await { + tracing::error!("Failed to update network info: {e}"); + tracing::debug!("{e:?}"); + } + ip_info.changed().await; + } + }); + Ok(Self { + shutdown: false, + data, + sync_task, + }) + } + + pub async fn bind( + &self, + id: HostId, + internal_port: u16, + options: BindOptions, + ) -> Result<(), Error> { + let mut data = self.data.lock().await; + let pkg_id = &data.id; + let ctrl = data.net_controller()?; + let host = ctrl + .db + .mutate(|db| { + let mut ports = db.as_private().as_available_ports().de()?; + let host = host_for(db, pkg_id.as_ref(), &id)?; + host.add_binding(&mut ports, internal_port, options)?; + let host = host.de()?; + db.as_private_mut().as_available_ports_mut().ser(&ports)?; + Ok(host) + }) + .await?; + data.update(&*ctrl, id, host).await + } + + pub async fn clear_bindings(&self, except: BTreeSet) -> Result<(), Error> { + let mut data = self.data.lock().await; + let ctrl = data.net_controller()?; + data.clear_bindings(&*ctrl, except).await + } + + pub async fn update(&self, id: HostId, host: Host) -> Result<(), Error> { + let mut data = self.data.lock().await; + let ctrl = data.net_controller()?; + data.update(&*ctrl, id, host).await + } + + pub async fn sync_host(&self, id: HostId) -> Result<(), Error> { + let mut data = self.data.lock().await; + let ctrl = data.net_controller()?; + let host = host_for(&mut ctrl.db.peek().await, data.id.as_ref(), &id)?.de()?; + data.update(&*ctrl, id, host).await + } + pub async fn remove_all(mut self) -> Result<(), Error> { - self.shutdown = true; - if let Some(ctrl) = Weak::upgrade(&self.controller) { - self.clear_bindings(Default::default()).await?; + self.sync_task.abort(); + let mut data = self.data.lock().await; + if let Some(ctrl) = Weak::upgrade(&data.controller) { + self.shutdown = true; + data.clear_bindings(&*ctrl, Default::default()).await?; + drop(ctrl); Ok(()) } else { @@ -653,26 +718,15 @@ impl NetService { } } - pub fn get_ip(&self) -> Ipv4Addr { - self.ip + pub async fn get_ip(&self) -> Ipv4Addr { + self.data.lock().await.ip } } impl Drop for NetService { fn drop(&mut self) { if !self.shutdown { - tracing::debug!("Dropping NetService for {}", self.id); - let svc = std::mem::replace( - self, - NetService { - shutdown: true, - id: Default::default(), - ip: Ipv4Addr::new(0, 0, 0, 0), - dns: Default::default(), - controller: Default::default(), - binds: BTreeMap::new(), - }, - ); + let svc = std::mem::replace(self, Self::dummy()); tokio::spawn(async move { svc.remove_all().await.log_err() }); } } diff --git a/core/startos/src/net/network_interface.rs b/core/startos/src/net/network_interface.rs index 920bdd4e4..bda34fc40 100644 --- a/core/startos/src/net/network_interface.rs +++ b/core/startos/src/net/network_interface.rs @@ -27,6 +27,7 @@ use zbus::{proxy, Connection}; use crate::context::{CliContext, RpcContext}; use crate::db::model::public::{IpInfo, NetworkInterfaceInfo, NetworkInterfaceType}; use crate::db::model::Database; +use crate::net::forward::START9_BRIDGE_IFACE; use crate::net::utils::{ipv6_is_link_local, ipv6_is_local}; use crate::prelude::*; use crate::util::future::Until; @@ -319,7 +320,10 @@ impl<'a> StubStream<'a> for SignalStream<'a> { } #[instrument(skip_all)] -async fn watcher(write_to: Watch>) { +async fn watcher( + write_to: Watch>, + lxcbr_status: Watch, +) { loop { let res: Result<(), Error> = async { let connection = Connection::system().await?; @@ -357,19 +361,27 @@ async fn watcher(write_to: Watch> let mut ifaces = BTreeSet::new(); let mut jobs = Vec::new(); for device in devices { + use futures::future::Either; + let device_proxy = device::DeviceProxy::new(&connection, device.clone()).await?; let iface = InternedString::intern(device_proxy.ip_interface().await?); if iface.is_empty() { continue; + } else if &*iface == START9_BRIDGE_IFACE { + jobs.push(Either::Left(watch_activated( + &connection, + device_proxy.clone(), + &lxcbr_status, + ))); } - jobs.push(watch_ip( + jobs.push(Either::Right(watch_ip( &connection, device_proxy.clone(), iface.clone(), &write_to, - )); + ))); ifaces.insert(iface); } @@ -588,13 +600,49 @@ async fn watch_ip( } } +#[instrument(skip(_connection, device_proxy, write_to))] +async fn watch_activated( + _connection: &Connection, + device_proxy: device::DeviceProxy<'_>, + write_to: &Watch, +) -> Result<(), Error> { + let mut until = Until::new() + .with_stream( + device_proxy + .receive_active_connection_changed() + .await + .stub(), + ) + .with_stream( + device_proxy + .receive_state_changed() + .await? + .into_inner() + .stub(), + ); + + loop { + until + .run(async { + write_to.send(device_proxy._state().await? == 100); + Ok(()) + }) + .await?; + } +} + pub struct NetworkInterfaceController { db: TypedPatchDb, + lxcbr_status: Watch, ip_info: Watch>, _watcher: NonDetachingJoinHandle<()>, listeners: SyncMutex>>, } impl NetworkInterfaceController { + pub fn lxcbr_status(&self) -> Watch { + self.lxcbr_status.clone_unseen() + } + pub fn subscribe(&self) -> Watch> { self.ip_info.clone_unseen() } @@ -665,8 +713,10 @@ impl NetworkInterfaceController { } pub fn new(db: TypedPatchDb) -> Self { let mut ip_info = Watch::new(BTreeMap::new()); + let lxcbr_status = Watch::new(false); Self { db: db.clone(), + lxcbr_status: lxcbr_status.clone(), ip_info: ip_info.clone(), _watcher: tokio::spawn(async move { match db @@ -688,7 +738,7 @@ impl NetworkInterfaceController { tracing::debug!("{e:?}"); } }; - tokio::join!(watcher(ip_info.clone()), async { + tokio::join!(watcher(ip_info.clone(), lxcbr_status), async { let res: Result<(), Error> = async { loop { if let Err(e) = async { diff --git a/core/startos/src/net/vhost.rs b/core/startos/src/net/vhost.rs index dc6f422bf..cbc1cc916 100644 --- a/core/startos/src/net/vhost.rs +++ b/core/startos/src/net/vhost.rs @@ -1,6 +1,5 @@ use std::collections::{BTreeMap, BTreeSet}; use std::net::{IpAddr, SocketAddr}; -use std::str::FromStr; use std::sync::{Arc, Weak}; use std::time::Duration; @@ -328,17 +327,23 @@ impl VHostServer { .headers() .get(http::header::HOST) .and_then(|host| host.to_str().ok()); - let uri = Uri::from_parts({ - let mut parts = req.uri().to_owned().into_parts(); - parts.scheme = Some("https".parse()?); - parts.authority = - host.map(FromStr::from_str).transpose()?; - parts - })?; - Response::builder() - .status(http::StatusCode::TEMPORARY_REDIRECT) - .header(http::header::LOCATION, uri.to_string()) - .body(Body::default()) + if let Some(host) = host { + let uri = Uri::from_parts({ + let mut parts = + req.uri().to_owned().into_parts(); + parts.scheme = Some("https".parse()?); + parts.authority = Some(host.parse()?); + parts + })?; + Response::builder() + .status(http::StatusCode::TEMPORARY_REDIRECT) + .header(http::header::LOCATION, uri.to_string()) + .body(Body::default()) + } else { + Response::builder() + .status(http::StatusCode::BAD_REQUEST) + .body(Body::from("Host header required")) + } } .await { diff --git a/core/startos/src/net/wifi.rs b/core/startos/src/net/wifi.rs index b2e59c20f..9b858aafe 100644 --- a/core/startos/src/net/wifi.rs +++ b/core/startos/src/net/wifi.rs @@ -899,9 +899,8 @@ impl TypedValueParser for CountryCodeParser { #[instrument(skip_all)] pub async fn synchronize_network_manager>( main_datadir: P, - wifi: &mut WifiInfo, + wifi: &WifiInfo, ) -> Result<(), Error> { - wifi.interface = find_wifi_iface().await?; let persistent = main_datadir.as_ref().join("system-connections"); if tokio::fs::metadata(&persistent).await.is_err() { diff --git a/core/startos/src/service/effects/net/bind.rs b/core/startos/src/service/effects/net/bind.rs index 2f3edb07b..2db3eb2ca 100644 --- a/core/startos/src/service/effects/net/bind.rs +++ b/core/startos/src/service/effects/net/bind.rs @@ -1,14 +1,12 @@ use models::{HostId, PackageId}; use crate::net::host::binding::{BindId, BindOptions, NetInfo}; -use crate::net::host::HostKind; use crate::service::effects::prelude::*; #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export)] pub struct BindParams { - kind: HostKind, id: HostId, internal_port: u16, #[serde(flatten)] @@ -17,15 +15,18 @@ pub struct BindParams { pub async fn bind( context: EffectContext, BindParams { - kind, id, internal_port, options, }: BindParams, ) -> Result<(), Error> { let context = context.deref()?; - let mut svc = context.seed.persistent_container.net_service.lock().await; - svc.bind(kind, id, internal_port, options).await + context + .seed + .persistent_container + .net_service + .bind(id, internal_port, options) + .await } #[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)] @@ -41,8 +42,12 @@ pub async fn clear_bindings( ClearBindingsParams { except }: ClearBindingsParams, ) -> Result<(), Error> { let context = context.deref()?; - let mut svc = context.seed.persistent_container.net_service.lock().await; - svc.clear_bindings(except.into_iter().collect()).await?; + context + .seed + .persistent_container + .net_service + .clear_bindings(except.into_iter().collect()) + .await?; Ok(()) } diff --git a/core/startos/src/service/effects/net/info.rs b/core/startos/src/service/effects/net/info.rs index c33a1a81e..fe6623f44 100644 --- a/core/startos/src/service/effects/net/info.rs +++ b/core/startos/src/service/effects/net/info.rs @@ -4,6 +4,5 @@ use crate::service::effects::prelude::*; pub async fn get_container_ip(context: EffectContext) -> Result { let context = context.deref()?; - let net_service = context.seed.persistent_container.net_service.lock().await; - Ok(net_service.get_ip()) + Ok(context.seed.persistent_container.net_service.get_ip().await) } diff --git a/core/startos/src/service/mod.rs b/core/startos/src/service/mod.rs index 5bc7fd999..2a18ea518 100644 --- a/core/startos/src/service/mod.rs +++ b/core/startos/src/service/mod.rs @@ -605,23 +605,12 @@ impl Service { }) } - pub async fn update_host(&self, host_id: HostId) -> Result<(), Error> { - let mut service = self.seed.persistent_container.net_service.lock().await; - let host = self - .seed - .ctx - .db - .peek() + pub async fn sync_host(&self, host_id: HostId) -> Result<(), Error> { + self.seed + .persistent_container + .net_service + .sync_host(host_id) .await - .as_public() - .as_package_data() - .as_idx(&self.seed.id) - .or_not_found(&self.seed.id)? - .as_hosts() - .as_idx(&host_id) - .or_not_found(&host_id)? - .de()?; - service.update(host_id, host).await } } diff --git a/core/startos/src/service/persistent_container.rs b/core/startos/src/service/persistent_container.rs index d99d9bb49..910255e7d 100644 --- a/core/startos/src/service/persistent_container.rs +++ b/core/startos/src/service/persistent_container.rs @@ -110,7 +110,7 @@ pub struct PersistentContainer { pub(super) images: BTreeMap>, pub(super) subcontainers: Arc>>, pub(super) state: Arc>, - pub(super) net_service: Mutex, + pub(super) net_service: NetService, destroyed: bool, } @@ -285,7 +285,7 @@ impl PersistentContainer { images, subcontainers: Arc::new(Mutex::new(BTreeMap::new())), state: Arc::new(watch::channel(ServiceState::new(start)).0), - net_service: Mutex::new(net_service), + net_service, destroyed: false, }) } diff --git a/core/startos/src/service/service_actor.rs b/core/startos/src/service/service_actor.rs index bb30d2a98..a56c92288 100644 --- a/core/startos/src/service/service_actor.rs +++ b/core/startos/src/service/service_actor.rs @@ -37,38 +37,6 @@ impl Actor for ServiceActor { } } }); - let seed = self.0.clone(); - let mut ip_info = seed.ctx.net_controller.net_iface.subscribe(); - jobs.add_job(async move { - loop { - if let Err(e) = async { - let mut service = seed.persistent_container.net_service.lock().await; - let hosts = seed - .ctx - .db - .peek() - .await - .as_public() - .as_package_data() - .as_idx(&seed.id) - .or_not_found(&seed.id)? - .as_hosts() - .de()?; - for (host_id, host) in hosts.0 { - service.update(host_id, host).await?; - } - - Ok::<_, Error>(()) - } - .await - { - tracing::error!("Error syncronizing net host after network change: {e}"); - tracing::debug!("{e:?}"); - } - - ip_info.changed().await; - } - }); } } diff --git a/core/startos/src/service/service_map.rs b/core/startos/src/service/service_map.rs index 104e191ba..de450706e 100644 --- a/core/startos/src/service/service_map.rs +++ b/core/startos/src/service/service_map.rs @@ -4,7 +4,8 @@ use std::time::Duration; use color_eyre::eyre::eyre; use futures::future::BoxFuture; -use futures::{Future, FutureExt}; +use futures::stream::FuturesUnordered; +use futures::{Future, FutureExt, StreamExt}; use helpers::NonDetachingJoinHandle; use imbl::OrdMap; use imbl_value::InternedString; @@ -68,8 +69,12 @@ impl ServiceMap { progress.start(); let ids = ctx.db.peek().await.as_public().as_package_data().keys()?; progress.set_total(ids.len() as u64); - for id in ids { - if let Err(e) = self.load(ctx, &id, LoadDisposition::Retry).await { + let mut jobs = FuturesUnordered::new(); + for id in &ids { + jobs.push(self.load(ctx, id, LoadDisposition::Retry)); + } + while let Some(res) = jobs.next().await { + if let Err(e) = res { tracing::error!("Error loading installed package as service: {e}"); tracing::debug!("{e:?}"); } diff --git a/core/startos/src/setup.rs b/core/startos/src/setup.rs index e9109cabe..186fbb0c4 100644 --- a/core/startos/src/setup.rs +++ b/core/startos/src/setup.rs @@ -31,7 +31,7 @@ use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard}; use crate::disk::util::{pvscan, recovery_info, DiskInfo, StartOsRecoveryInfo}; use crate::disk::REPAIR_DISK_PATH; use crate::init::{init, InitPhases, InitResult}; -use crate::net::net_controller::PreInitNetController; +use crate::net::net_controller::NetController; use crate::net::ssl::root_ca_start_time; use crate::prelude::*; use crate::progress::{FullProgress, PhaseProgressTrackerHandle}; @@ -80,10 +80,11 @@ async fn setup_init( ctx: &SetupContext, password: Option, init_phases: InitPhases, -) -> Result<(AccountInfo, PreInitNetController), Error> { - let InitResult { net_ctrl } = init(&ctx.webserver, &ctx.config, init_phases).await?; +) -> Result<(AccountInfo, InitResult), Error> { + let init_result = init(&ctx.webserver, &ctx.config, init_phases).await?; - let account = net_ctrl + let account = init_result + .net_ctrl .db .mutate(|m| { let mut account = AccountInfo::load(m)?; @@ -99,7 +100,7 @@ async fn setup_init( }) .await?; - Ok((account, net_ctrl)) + Ok((account, init_result)) } #[derive(Deserialize, Serialize, TS)] @@ -452,13 +453,13 @@ async fn fresh_setup( db.put(&ROOT, &Database::init(&account)?).await?; drop(db); - let InitResult { net_ctrl } = init(&ctx.webserver, &ctx.config, init_phases).await?; + let init_result = init(&ctx.webserver, &ctx.config, init_phases).await?; let rpc_ctx = RpcContext::init( &ctx.webserver, &ctx.config, guid, - Some(net_ctrl), + Some(init_result), rpc_ctx_phases, ) .await?; diff --git a/core/startos/src/util/sync.rs b/core/startos/src/util/sync.rs index ca7b4c6bb..d6099cb5b 100644 --- a/core/startos/src/util/sync.rs +++ b/core/startos/src/util/sync.rs @@ -77,6 +77,14 @@ impl Watch { pub async fn changed(&mut self) { futures::future::poll_fn(|cx| self.poll_changed(cx)).await } + pub async fn wait_for bool>(&mut self, mut f: F) { + loop { + if self.peek(&mut f) { + break; + } + self.changed().await; + } + } pub fn send_if_modified bool>(&self, modify: F) -> bool { self.shared.mutate(|shared| { let changed = modify(&mut shared.data); diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index 3c1687ea9..966379470 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -30,8 +30,9 @@ mod v0_3_6_alpha_9; mod v0_3_6_alpha_10; mod v0_3_6_alpha_11; +mod v0_3_6_alpha_12; -pub type Current = v0_3_6_alpha_11::Version; // VERSION_BUMP +pub type Current = v0_3_6_alpha_12::Version; // VERSION_BUMP impl Current { #[instrument(skip(self, db))] @@ -113,6 +114,7 @@ enum Version { V0_3_6_alpha_9(Wrapper), V0_3_6_alpha_10(Wrapper), V0_3_6_alpha_11(Wrapper), + V0_3_6_alpha_12(Wrapper), Other(exver::Version), } @@ -148,6 +150,7 @@ impl Version { Self::V0_3_6_alpha_9(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_10(v) => DynVersion(Box::new(v.0)), Self::V0_3_6_alpha_11(v) => DynVersion(Box::new(v.0)), + Self::V0_3_6_alpha_12(v) => DynVersion(Box::new(v.0)), Self::Other(v) => { return Err(Error::new( eyre!("unknown version {v}"), @@ -175,6 +178,7 @@ impl Version { Version::V0_3_6_alpha_9(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_10(Wrapper(x)) => x.semver(), Version::V0_3_6_alpha_11(Wrapper(x)) => x.semver(), + Version::V0_3_6_alpha_12(Wrapper(x)) => x.semver(), Version::Other(x) => x.clone(), } } diff --git a/core/startos/src/version/v0_3_6_alpha_0.rs b/core/startos/src/version/v0_3_6_alpha_0.rs index 7c594a9f9..b7f2ba2e4 100644 --- a/core/startos/src/version/v0_3_6_alpha_0.rs +++ b/core/startos/src/version/v0_3_6_alpha_0.rs @@ -478,7 +478,7 @@ async fn previous_account_info(pg: &sqlx::Pool) -> Result>, _>("tor_key") .with_ctx(|_| (ErrorKind::Database, "tor_key"))? @@ -503,7 +503,7 @@ async fn previous_account_info(pg: &sqlx::Pool) -> Result Result { + Ok(()) + } + fn semver(self) -> exver::Version { + V0_3_6_alpha_12.clone() + } + fn compat(self) -> &'static VersionRange { + &V0_3_0_COMPAT + } + fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> { + let bindings: BTreeMap = [( + 80, + json!({ + "enabled": false, + "options": { + "preferredExternalPort": 80, + "addSsl": { + "preferredExternalPort": 443, + "alpn": { "specified": [ "http/1.1", "h2" ] }, + }, + "secure": null, + }, + "net": { + "assignedPort": null, + "assignedSslPort": 443, + "public": false, + } + }), + )] + .into_iter() + .collect(); + let onion = db["public"]["serverInfo"]["onionAddress"].clone(); + db["public"]["serverInfo"]["host"] = json!({ + "bindings": bindings, + "onions": [onion], + "domains": {}, + "hostnameInfo": {}, + }); + + Ok(()) + } + fn down(self, _db: &mut Value) -> Result<(), Error> { + Ok(()) + } +} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 9a9ca8f48..000000000 --- a/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "start-os", - "lockfileVersion": 2, - "requires": true, - "packages": {} -} diff --git a/patch-db b/patch-db index 2600a784a..36eb59b79 160000 --- a/patch-db +++ b/patch-db @@ -1 +1 @@ -Subproject commit 2600a784a9899a6f8e0c9abe0bf4c4ce48cb85a9 +Subproject commit 36eb59b79efec614fb4f94ed925336e97881a2f7 diff --git a/sdk/base/lib/interfaces/Host.ts b/sdk/base/lib/interfaces/Host.ts index b90dc1c60..53419357f 100644 --- a/sdk/base/lib/interfaces/Host.ts +++ b/sdk/base/lib/interfaces/Host.ts @@ -77,19 +77,18 @@ type BindOptionsByKnownProtocol = preferredExternalPort?: number addSsl?: AddSslOptions } -export type BindOptionsByProtocol = BindOptionsByKnownProtocol | BindOptions - -export type HostKind = BindParams["kind"] +export type BindOptionsByProtocol = + | BindOptionsByKnownProtocol + | (BindOptions & { protocol: null }) const hasStringProtocol = object({ protocol: string, }).test -export class Host { +export class MultiHost { constructor( readonly options: { effects: Effects - kind: HostKind id: string }, ) {} @@ -113,7 +112,7 @@ export class Host { async bindPort( internalPort: number, options: BindOptionsByProtocol, - ): Promise> { + ): Promise { if (hasStringProtocol(options)) { return await this.bindPortForKnown(options, internalPort) } else { @@ -130,7 +129,6 @@ export class Host { }, ) { const binderOptions = { - kind: this.options.kind, id: this.options.id, internalPort, ...options, @@ -163,7 +161,6 @@ export class Host { const secure: Security | null = !protoInfo.secure ? null : { ssl: false } await this.options.effects.bind({ - kind: this.options.kind, id: this.options.id, internalPort, preferredExternalPort, @@ -190,21 +187,3 @@ function inObject( ): obj is { [K in Key]: unknown } { return key in obj } - -// export class StaticHost extends Host { -// constructor(options: { effects: Effects; id: string }) { -// super({ ...options, kind: "static" }) -// } -// } - -// export class SingleHost extends Host { -// constructor(options: { effects: Effects; id: string }) { -// super({ ...options, kind: "single" }) -// } -// } - -export class MultiHost extends Host { - constructor(options: { effects: Effects; id: string }) { - super({ ...options, kind: "multi" }) - } -} diff --git a/sdk/base/lib/interfaces/Origin.ts b/sdk/base/lib/interfaces/Origin.ts index 9985176e4..dd688b3c9 100644 --- a/sdk/base/lib/interfaces/Origin.ts +++ b/sdk/base/lib/interfaces/Origin.ts @@ -1,11 +1,11 @@ import { AddressInfo } from "../types" import { AddressReceipt } from "./AddressReceipt" -import { Host, Scheme } from "./Host" +import { MultiHost, Scheme } from "./Host" import { ServiceInterfaceBuilder } from "./ServiceInterfaceBuilder" -export class Origin { +export class Origin { constructor( - readonly host: T, + readonly host: MultiHost, readonly internalPort: number, readonly scheme: string | null, readonly sslScheme: string | null, diff --git a/sdk/base/lib/osBindings/BindParams.ts b/sdk/base/lib/osBindings/BindParams.ts index fcc450476..9064a33b1 100644 --- a/sdk/base/lib/osBindings/BindParams.ts +++ b/sdk/base/lib/osBindings/BindParams.ts @@ -1,11 +1,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { AddSslOptions } from "./AddSslOptions" import type { HostId } from "./HostId" -import type { HostKind } from "./HostKind" import type { Security } from "./Security" export type BindParams = { - kind: HostKind id: HostId internalPort: number preferredExternalPort: number diff --git a/sdk/base/lib/osBindings/Host.ts b/sdk/base/lib/osBindings/Host.ts index 5436e9955..041e1c9bc 100644 --- a/sdk/base/lib/osBindings/Host.ts +++ b/sdk/base/lib/osBindings/Host.ts @@ -1,11 +1,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { BindInfo } from "./BindInfo" import type { DomainConfig } from "./DomainConfig" -import type { HostKind } from "./HostKind" import type { HostnameInfo } from "./HostnameInfo" export type Host = { - kind: HostKind bindings: { [key: number]: BindInfo } onions: string[] domains: { [key: string]: DomainConfig } diff --git a/sdk/base/lib/osBindings/HostKind.ts b/sdk/base/lib/osBindings/HostKind.ts deleted file mode 100644 index 3c2f5ad87..000000000 --- a/sdk/base/lib/osBindings/HostKind.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export type HostKind = "multi" diff --git a/sdk/base/lib/osBindings/ServerInfo.ts b/sdk/base/lib/osBindings/ServerInfo.ts index 6eec14745..5779fa7d5 100644 --- a/sdk/base/lib/osBindings/ServerInfo.ts +++ b/sdk/base/lib/osBindings/ServerInfo.ts @@ -2,6 +2,7 @@ import type { AcmeProvider } from "./AcmeProvider" import type { AcmeSettings } from "./AcmeSettings" import type { Governor } from "./Governor" +import type { Host } from "./Host" import type { LshwDevice } from "./LshwDevice" import type { NetworkInterfaceInfo } from "./NetworkInterfaceInfo" import type { ServerStatus } from "./ServerStatus" @@ -13,16 +14,11 @@ export type ServerInfo = { platform: string id: string hostname: string + host: Host version: string packageVersionCompat: string postInitMigrationTodos: string[] lastBackup: string | null - lanAddress: string - onionAddress: string - /** - * for backwards compatibility - */ - torAddress: string networkInterfaces: { [key: string]: NetworkInterfaceInfo } acme: { [key: AcmeProvider]: AcmeSettings } statusInfo: ServerStatus diff --git a/sdk/base/lib/osBindings/SetupResult.ts b/sdk/base/lib/osBindings/SetupResult.ts index d81c7f039..3147187c1 100644 --- a/sdk/base/lib/osBindings/SetupResult.ts +++ b/sdk/base/lib/osBindings/SetupResult.ts @@ -1,7 +1,7 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. export type SetupResult = { - torAddress: string + torAddresses: Array hostname: string lanAddress: string rootCa: string diff --git a/sdk/base/lib/osBindings/index.ts b/sdk/base/lib/osBindings/index.ts index 3c16f6e70..8ba83c9e0 100644 --- a/sdk/base/lib/osBindings/index.ts +++ b/sdk/base/lib/osBindings/index.ts @@ -4,13 +4,13 @@ export { AcmeSettings } from "./AcmeSettings" export { ActionId } from "./ActionId" export { ActionInput } from "./ActionInput" export { ActionMetadata } from "./ActionMetadata" +export { ActionRequest } from "./ActionRequest" export { ActionRequestCondition } from "./ActionRequestCondition" export { ActionRequestEntry } from "./ActionRequestEntry" export { ActionRequestInput } from "./ActionRequestInput" export { ActionRequestTrigger } from "./ActionRequestTrigger" -export { ActionRequest } from "./ActionRequest" -export { ActionResultMember } from "./ActionResultMember" export { ActionResult } from "./ActionResult" +export { ActionResultMember } from "./ActionResultMember" export { ActionResultV0 } from "./ActionResultV0" export { ActionResultV1 } from "./ActionResultV1" export { ActionResultValue } from "./ActionResultValue" @@ -20,13 +20,13 @@ export { AddAdminParams } from "./AddAdminParams" export { AddAssetParams } from "./AddAssetParams" export { AddCategoryParams } from "./AddCategoryParams" export { AddPackageParams } from "./AddPackageParams" -export { AddressInfo } from "./AddressInfo" export { AddSslOptions } from "./AddSslOptions" export { AddVersionParams } from "./AddVersionParams" +export { AddressInfo } from "./AddressInfo" export { Alerts } from "./Alerts" export { Algorithm } from "./Algorithm" -export { AllowedStatuses } from "./AllowedStatuses" export { AllPackageData } from "./AllPackageData" +export { AllowedStatuses } from "./AllowedStatuses" export { AlpnInfo } from "./AlpnInfo" export { AnySignature } from "./AnySignature" export { AnySigningKey } from "./AnySigningKey" @@ -38,9 +38,9 @@ export { BackupTargetFS } from "./BackupTargetFS" export { Base64 } from "./Base64" export { BindId } from "./BindId" export { BindInfo } from "./BindInfo" -export { BindingSetPublicParams } from "./BindingSetPublicParams" export { BindOptions } from "./BindOptions" export { BindParams } from "./BindParams" +export { BindingSetPublicParams } from "./BindingSetPublicParams" export { Blake3Commitment } from "./Blake3Commitment" export { BlockDev } from "./BlockDev" export { BuildArg } from "./BuildArg" @@ -60,11 +60,11 @@ export { CreateSubcontainerFsParams } from "./CreateSubcontainerFsParams" export { CurrentDependencies } from "./CurrentDependencies" export { CurrentDependencyInfo } from "./CurrentDependencyInfo" export { DataUrl } from "./DataUrl" +export { DepInfo } from "./DepInfo" export { Dependencies } from "./Dependencies" export { DependencyKind } from "./DependencyKind" export { DependencyMetadata } from "./DependencyMetadata" export { DependencyRequirement } from "./DependencyRequirement" -export { DepInfo } from "./DepInfo" export { Description } from "./Description" export { DestroySubcontainerFsParams } from "./DestroySubcontainerFsParams" export { DeviceFilter } from "./DeviceFilter" @@ -84,8 +84,8 @@ export { GetHostInfoParams } from "./GetHostInfoParams" export { GetOsAssetParams } from "./GetOsAssetParams" export { GetOsVersionParams } from "./GetOsVersionParams" export { GetPackageParams } from "./GetPackageParams" -export { GetPackageResponseFull } from "./GetPackageResponseFull" export { GetPackageResponse } from "./GetPackageResponse" +export { GetPackageResponseFull } from "./GetPackageResponseFull" export { GetServiceInterfaceParams } from "./GetServiceInterfaceParams" export { GetServicePortForwardParams } from "./GetServicePortForwardParams" export { GetSslCertificateParams } from "./GetSslCertificateParams" @@ -98,22 +98,21 @@ export { Governor } from "./Governor" export { Guid } from "./Guid" export { HardwareRequirements } from "./HardwareRequirements" export { HealthCheckId } from "./HealthCheckId" +export { Host } from "./Host" export { HostAddress } from "./HostAddress" export { HostId } from "./HostId" -export { HostKind } from "./HostKind" export { HostnameInfo } from "./HostnameInfo" export { Hosts } from "./Hosts" -export { Host } from "./Host" export { ImageConfig } from "./ImageConfig" export { ImageId } from "./ImageId" export { ImageMetadata } from "./ImageMetadata" export { ImageSource } from "./ImageSource" export { InitProgressRes } from "./InitProgressRes" +export { InstallParams } from "./InstallParams" export { InstalledState } from "./InstalledState" export { InstalledVersionParams } from "./InstalledVersionParams" export { InstallingInfo } from "./InstallingInfo" export { InstallingState } from "./InstallingState" -export { InstallParams } from "./InstallParams" export { IpHostname } from "./IpHostname" export { IpInfo } from "./IpInfo" export { ListPackageSignersParams } from "./ListPackageSignersParams" @@ -137,14 +136,14 @@ export { NetworkInterfaceSetPublicParams } from "./NetworkInterfaceSetPublicPara export { NetworkInterfaceType } from "./NetworkInterfaceType" export { OnionHostname } from "./OnionHostname" export { OsIndex } from "./OsIndex" -export { OsVersionInfoMap } from "./OsVersionInfoMap" export { OsVersionInfo } from "./OsVersionInfo" +export { OsVersionInfoMap } from "./OsVersionInfoMap" export { PackageDataEntry } from "./PackageDataEntry" export { PackageDetailLevel } from "./PackageDetailLevel" export { PackageId } from "./PackageId" export { PackageIndex } from "./PackageIndex" -export { PackageInfoShort } from "./PackageInfoShort" export { PackageInfo } from "./PackageInfo" +export { PackageInfoShort } from "./PackageInfoShort" export { PackageSignerParams } from "./PackageSignerParams" export { PackageState } from "./PackageState" export { PackageVersionInfo } from "./PackageVersionInfo" @@ -166,18 +165,18 @@ export { Security } from "./Security" export { ServerInfo } from "./ServerInfo" export { ServerSpecs } from "./ServerSpecs" export { ServerStatus } from "./ServerStatus" -export { ServiceInterfaceId } from "./ServiceInterfaceId" export { ServiceInterface } from "./ServiceInterface" +export { ServiceInterfaceId } from "./ServiceInterfaceId" export { ServiceInterfaceType } from "./ServiceInterfaceType" +export { Session } from "./Session" export { SessionList } from "./SessionList" export { Sessions } from "./Sessions" -export { Session } from "./Session" export { SetDataVersionParams } from "./SetDataVersionParams" export { SetDependenciesParams } from "./SetDependenciesParams" export { SetHealth } from "./SetHealth" export { SetIconParams } from "./SetIconParams" -export { SetMainStatusStatus } from "./SetMainStatusStatus" export { SetMainStatus } from "./SetMainStatus" +export { SetMainStatusStatus } from "./SetMainStatusStatus" export { SetNameParams } from "./SetNameParams" export { SetStoreParams } from "./SetStoreParams" export { SetupExecuteParams } from "./SetupExecuteParams" @@ -192,7 +191,7 @@ export { TestSmtpParams } from "./TestSmtpParams" export { UnsetPublicParams } from "./UnsetPublicParams" export { UpdatingState } from "./UpdatingState" export { VerifyCifsParams } from "./VerifyCifsParams" -export { VersionSignerParams } from "./VersionSignerParams" export { Version } from "./Version" +export { VersionSignerParams } from "./VersionSignerParams" export { VolumeId } from "./VolumeId" export { WifiInfo } from "./WifiInfo" diff --git a/sdk/base/lib/util/patterns.ts b/sdk/base/lib/util/patterns.ts index 46f67b6b8..a61e4269c 100644 --- a/sdk/base/lib/util/patterns.ts +++ b/sdk/base/lib/util/patterns.ts @@ -2,63 +2,68 @@ import { Pattern } from "../actions/input/inputSpecTypes" import * as regexes from "./regexes" export const ipv6: Pattern = { - regex: regexes.ipv6.source, + regex: regexes.ipv6.matches(), description: "Must be a valid IPv6 address", } export const ipv4: Pattern = { - regex: regexes.ipv4.source, + regex: regexes.ipv4.matches(), description: "Must be a valid IPv4 address", } export const hostname: Pattern = { - regex: regexes.hostname.source, + regex: regexes.hostname.matches(), description: "Must be a valid hostname", } export const localHostname: Pattern = { - regex: regexes.localHostname.source, + regex: regexes.localHostname.matches(), description: 'Must be a valid ".local" hostname', } export const torHostname: Pattern = { - regex: regexes.torHostname.source, + regex: regexes.torHostname.matches(), description: 'Must be a valid Tor (".onion") hostname', } export const url: Pattern = { - regex: regexes.url.source, + regex: regexes.url.matches(), description: "Must be a valid URL", } export const localUrl: Pattern = { - regex: regexes.localUrl.source, + regex: regexes.localUrl.matches(), description: 'Must be a valid ".local" URL', } export const torUrl: Pattern = { - regex: regexes.torUrl.source, + regex: regexes.torUrl.matches(), description: 'Must be a valid Tor (".onion") URL', } export const ascii: Pattern = { - regex: regexes.ascii.source, + regex: regexes.ascii.matches(), description: "May only contain ASCII characters. See https://www.w3schools.com/charsets/ref_html_ascii.asp", } +export const domain: Pattern = { + regex: regexes.domain.matches(), + description: "Must be a valid Fully Qualified Domain Name", +} + export const email: Pattern = { - regex: regexes.email.source, + regex: regexes.email.matches(), description: "Must be a valid email address", } export const emailWithName: Pattern = { - regex: regexes.emailWithName.source, + regex: regexes.emailWithName.matches(), description: "Must be a valid email address, optionally with a name", } export const base64: Pattern = { - regex: regexes.base64.source, + regex: regexes.base64.matches(), description: "May only contain base64 characters. See https://base64.guru/learn/base64-characters", } diff --git a/sdk/base/lib/util/regexes.ts b/sdk/base/lib/util/regexes.ts index e4e11766a..a2a8cde7a 100644 --- a/sdk/base/lib/util/regexes.ts +++ b/sdk/base/lib/util/regexes.ts @@ -1,38 +1,71 @@ +export class ComposableRegex { + readonly regex: RegExp + constructor(regex: RegExp | string) { + if (regex instanceof RegExp) { + this.regex = regex + } else { + this.regex = new RegExp(regex) + } + } + asExpr(): string { + return `(${this.regex.source})` + } + matches(): string { + return `^${this.regex.source}$` + } + contains(): string { + return this.regex.source + } +} + // https://ihateregex.io/expr/ipv6/ -export const ipv6 = - /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/ +export const ipv6 = new ComposableRegex( + /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, +) // https://ihateregex.io/expr/ipv4/ -export const ipv4 = - /(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/ +export const ipv4 = new ComposableRegex( + /(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/, +) -export const hostname = - /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/ +export const hostname = new ComposableRegex( + /(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])/, +) -export const localHostname = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local/ +export const localHostname = new ComposableRegex( + /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local/, +) -export const torHostname = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion/ +export const torHostname = new ComposableRegex( + /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion/, +) // https://ihateregex.io/expr/url/ -export const url = - /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/ +export const url = new ComposableRegex( + /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/, +) -export const localUrl = - /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/ +export const localUrl = new ComposableRegex( + /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/, +) -export const torUrl = - /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/ +export const torUrl = new ComposableRegex( + /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/, +) // https://ihateregex.io/expr/ascii/ -export const ascii = /^[ -~]*$/ +export const ascii = new ComposableRegex(/[ -~]*/) + +export const domain = new ComposableRegex(/[A-Za-z0-9.-]+\.[A-Za-z]{2,}/) // https://www.regular-expressions.info/email.html -export const email = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/ +export const email = new ComposableRegex(`[A-Za-z0-9._%+-]+@${domain.asExpr()}`) -export const emailWithName = new RegExp( - `(${email.source})|([^<]*<(${email.source})>)`, +export const emailWithName = new ComposableRegex( + `${email.asExpr()}|([^<]*<${email.asExpr()}>)`, ) //https://rgxdb.com/r/1NUN74O6 -export const base64 = - /^(?:[a-zA-Z0-9+\/]{4})*(?:|(?:[a-zA-Z0-9+\/]{3}=)|(?:[a-zA-Z0-9+\/]{2}==)|(?:[a-zA-Z0-9+\/]{1}===))$/ +export const base64 = new ComposableRegex( + /(?:[a-zA-Z0-9+\/]{4})*(?:|(?:[a-zA-Z0-9+\/]{3}=)|(?:[a-zA-Z0-9+\/]{2}==)|(?:[a-zA-Z0-9+\/]{1}===))/, +) diff --git a/system-images/compat/Cargo.toml b/system-images/compat/Cargo.toml index e527c4150..d5fb24161 100644 --- a/system-images/compat/Cargo.toml +++ b/system-images/compat/Cargo.toml @@ -17,7 +17,7 @@ emver = { version = "0.1.7", git = "https://github.com/Start9Labs/emver-rs.git", ] } failure = "0.1.8" indexmap = { version = "1.6.2", features = ["serde"] } -imbl-value = { git = "https://github.com/Start9Labs/imbl-value.git" } +imbl-value = "0.1.2" itertools = "0.10.0" lazy_static = "1.4" linear-map = { version = "1.2", features = ["serde_impl"] } diff --git a/web/package-lock.json b/web/package-lock.json index 740020a3a..f218a6d82 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.11", + "version": "0.3.6-alpha.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "startos-ui", - "version": "0.3.6-alpha.11", + "version": "0.3.6-alpha.12", "license": "MIT", "dependencies": { "@angular/animations": "^14.1.0", @@ -126,7 +126,7 @@ "isomorphic-fetch": "^3.0.0", "lodash.merge": "^4.6.2", "mime-types": "^2.1.35", - "ts-matches": "^6.1.0", + "ts-matches": "^6.2.1", "yaml": "^2.2.2" }, "devDependencies": { diff --git a/web/package.json b/web/package.json index 800297407..3355c46cc 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "startos-ui", - "version": "0.3.6-alpha.11", + "version": "0.3.6-alpha.12", "author": "Start9 Labs, Inc", "homepage": "https://start9.com/", "license": "MIT", diff --git a/web/projects/setup-wizard/src/app/pages/success/download-doc/download-doc.component.html b/web/projects/setup-wizard/src/app/pages/success/download-doc/download-doc.component.html index ef8c32a49..60e25e48a 100644 --- a/web/projects/setup-wizard/src/app/pages/success/download-doc/download-doc.component.html +++ b/web/projects/setup-wizard/src/app/pages/success/download-doc/download-doc.component.html @@ -121,7 +121,7 @@ overflow: auto; " > - +

diff --git a/web/projects/setup-wizard/src/app/pages/success/success.page.ts b/web/projects/setup-wizard/src/app/pages/success/success.page.ts index aa0c7fc90..198ec3387 100644 --- a/web/projects/setup-wizard/src/app/pages/success/success.page.ts +++ b/web/projects/setup-wizard/src/app/pages/success/success.page.ts @@ -15,7 +15,7 @@ export class SuccessPage { {} as ElementRef private ctx: CanvasRenderingContext2D = {} as CanvasRenderingContext2D - torAddress?: string + torAddresses?: string[] lanAddress?: string cert?: string @@ -52,7 +52,7 @@ export class SuccessPage { const torAddress = this.document.getElementById('tor-addr') const lanAddress = this.document.getElementById('lan-addr') - if (torAddress) torAddress.innerHTML = this.torAddress! + if (torAddress) torAddress.innerHTML = this.torAddresses!.join('\n') if (lanAddress) lanAddress.innerHTML = this.lanAddress! this.document @@ -76,7 +76,9 @@ export class SuccessPage { try { const ret = await this.api.complete() if (!this.isKiosk) { - this.torAddress = ret.torAddress.replace(/^https:/, 'http:') + this.torAddresses = ret.torAddresses.map(a => + a.replace(/^https:/, 'http:'), + ) this.lanAddress = ret.lanAddress.replace(/^https:/, 'http:') this.cert = ret.rootCa diff --git a/web/projects/setup-wizard/src/app/services/api/mock-api.service.ts b/web/projects/setup-wizard/src/app/services/api/mock-api.service.ts index a17f56a0c..e84ef5335 100644 --- a/web/projects/setup-wizard/src/app/services/api/mock-api.service.ts +++ b/web/projects/setup-wizard/src/app/services/api/mock-api.service.ts @@ -136,7 +136,7 @@ export class MockApiService extends ApiService { case 3: return { status: 'complete', - torAddress: 'https://asdafsadasdasasdasdfasdfasdf.onion', + torAddresses: ['https://asdafsadasdasasdasdfasdfasdf.onion'], hostname: 'adjective-noun', lanAddress: 'https://adjective-noun.local', rootCa: encodeBase64(rootCA), @@ -283,7 +283,7 @@ export class MockApiService extends ApiService { async complete(): Promise { await pauseFor(1000) return { - torAddress: 'https://asdafsadasdasasdasdfasdfasdf.onion', + torAddresses: ['https://asdafsadasdasasdasdfasdfasdf.onion'], hostname: 'adjective-noun', lanAddress: 'https://adjective-noun.local', rootCa: encodeBase64(rootCA), diff --git a/web/projects/shared/src/types/workspace-config.ts b/web/projects/shared/src/types/workspace-config.ts index d10c4b07e..0586b3560 100644 --- a/web/projects/shared/src/types/workspace-config.ts +++ b/web/projects/shared/src/types/workspace-config.ts @@ -13,7 +13,7 @@ export type WorkspaceConfig = { community: 'https://community-registry.start9.com/' } mocks: { - maskAs: 'tor' | 'local' | 'ip' | 'localhost' + maskAs: 'tor' | 'local' | 'localhost' | 'ipv4' | 'ipv6' | 'clearnet' // enables local development in secure mode maskAsHttps: boolean skipStartupAlerts: boolean diff --git a/web/projects/ui/src/app/app/preloader/preloader.component.ts b/web/projects/ui/src/app/app/preloader/preloader.component.ts index 70c5e2995..772c5c40b 100644 --- a/web/projects/ui/src/app/app/preloader/preloader.component.ts +++ b/web/projects/ui/src/app/app/preloader/preloader.component.ts @@ -45,7 +45,7 @@ const ICONS = [ 'eye-off-outline', 'eye-outline', 'file-tray-stacked-outline', - 'finger-print-outline', + 'finger-print', 'flash-outline', 'folder-open-outline', 'globe-outline', diff --git a/web/projects/ui/src/app/components/form/form-select/form-select.component.html b/web/projects/ui/src/app/components/form/form-select/form-select.component.html index 9149e8844..b8e79351a 100644 --- a/web/projects/ui/src/app/components/form/form-select/form-select.component.html +++ b/web/projects/ui/src/app/components/form/form-select/form-select.component.html @@ -7,7 +7,7 @@ [(ngModel)]="selected" (focusedChange)="onFocus($event)" > - {{ spec.name }}* + {{ spec.name }} *