diff --git a/console-webapp/angular.json b/console-webapp/angular.json index 562b5c020..a9f17c350 100644 --- a/console-webapp/angular.json +++ b/console-webapp/angular.json @@ -73,10 +73,10 @@ "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "browserTarget": "console-webapp:build:production" + "buildTarget": "console-webapp:build:production" }, "development": { - "browserTarget": "console-webapp:build:development" + "buildTarget": "console-webapp:build:development" } }, "defaultConfiguration": "development" @@ -84,7 +84,7 @@ "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "console-webapp:build" + "buildTarget": "console-webapp:build" } }, "test": { diff --git a/console-webapp/build.gradle b/console-webapp/build.gradle index a5c5a96f6..a9fcbb0bc 100644 --- a/console-webapp/build.gradle +++ b/console-webapp/build.gradle @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/package-lock.json b/console-webapp/package-lock.json index 5a466c12e..05db48693 100644 --- a/console-webapp/package-lock.json +++ b/console-webapp/package-lock.json @@ -57,25 +57,25 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@angular-devkit/architect": { - "version": "0.1702.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1702.1.tgz", - "integrity": "sha512-eYYtR3kCG0V7aHsL34O4v8W2nW6MX4+SebhBO2dHGz2nCAS09LPtyO2fZZGawPgXOrN0nkLfghghI0hJ0dDaOw==", + "version": "0.1703.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.1.tgz", + "integrity": "sha512-vkfvURv7O+3fHMTE9K+yUEiFS0v4JNYKsDP0LE1ChH5Ocy0bJXGcH2Cyz2W8qdJGDG/tKe41VzvOLpu88Xv3zQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "17.2.1", + "@angular-devkit/core": "17.3.1", "rxjs": "7.8.1" }, "engines": { @@ -94,70 +94,70 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.2.1.tgz", - "integrity": "sha512-Wq3ggliCMQCRVCucbjE4/9BJCN1KMSGfF6Bx1ke2B+vW3ElLt+M4x4Eeyg2dSPEYB7slgY9WOx7qtyOkUy15tQ==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.1.tgz", + "integrity": "sha512-e+hZvLVH5AvHCFbVtKRd5oJeFsEmjg7kK1V6hsVxH4YE2f2x399TSr+AGxwV+R3jnjZ67ujIeXXd0Uuf1RwcSg==", "dev": true, "dependencies": { - "@ampproject/remapping": "2.2.1", - "@angular-devkit/architect": "0.1702.1", - "@angular-devkit/build-webpack": "0.1702.1", - "@angular-devkit/core": "17.2.1", - "@babel/core": "7.23.9", + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1703.1", + "@angular-devkit/build-webpack": "0.1703.1", + "@angular-devkit/core": "17.3.1", + "@babel/core": "7.24.0", "@babel/generator": "7.23.6", "@babel/helper-annotate-as-pure": "7.22.5", "@babel/helper-split-export-declaration": "7.22.6", "@babel/plugin-transform-async-generator-functions": "7.23.9", "@babel/plugin-transform-async-to-generator": "7.23.3", - "@babel/plugin-transform-runtime": "7.23.9", - "@babel/preset-env": "7.23.9", - "@babel/runtime": "7.23.9", + "@babel/plugin-transform-runtime": "7.24.0", + "@babel/preset-env": "7.24.0", + "@babel/runtime": "7.24.0", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.2.1", + "@ngtools/webpack": "17.3.1", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", - "autoprefixer": "10.4.17", + "autoprefixer": "10.4.18", "babel-loader": "9.1.3", "babel-plugin-istanbul": "6.1.1", "browserslist": "^4.21.5", "copy-webpack-plugin": "11.0.0", - "critters": "0.0.20", + "critters": "0.0.22", "css-loader": "6.10.0", - "esbuild-wasm": "0.20.0", + "esbuild-wasm": "0.20.1", "fast-glob": "3.3.2", "http-proxy-middleware": "2.0.6", - "https-proxy-agent": "7.0.2", - "inquirer": "9.2.14", + "https-proxy-agent": "7.0.4", + "inquirer": "9.2.15", "jsonc-parser": "3.2.1", "karma-source-map-support": "1.4.0", "less": "4.2.0", "less-loader": "11.1.0", "license-webpack-plugin": "4.0.2", "loader-utils": "3.2.1", - "magic-string": "0.30.7", - "mini-css-extract-plugin": "2.8.0", + "magic-string": "0.30.8", + "mini-css-extract-plugin": "2.8.1", "mrmime": "2.0.0", "open": "8.4.2", "ora": "5.4.1", "parse5-html-rewriting-stream": "7.0.0", "picomatch": "4.0.1", - "piscina": "4.3.1", + "piscina": "4.4.0", "postcss": "8.4.35", - "postcss-loader": "8.1.0", + "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.1", - "sass": "1.70.0", - "sass-loader": "14.1.0", + "sass": "1.71.1", + "sass-loader": "14.1.1", "semver": "7.6.0", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", - "terser": "5.27.0", + "terser": "5.29.1", "tree-kill": "1.2.2", "tslib": "2.6.2", - "undici": "6.6.2", - "vite": "5.0.12", + "undici": "6.7.1", + "vite": "5.1.5", "watchpack": "2.4.0", - "webpack": "5.90.1", + "webpack": "5.90.3", "webpack-dev-middleware": "6.1.1", "webpack-dev-server": "4.15.1", "webpack-merge": "5.10.0", @@ -169,7 +169,7 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.20.0" + "esbuild": "0.20.1" }, "peerDependencies": { "@angular/compiler-cli": "^17.0.0", @@ -184,7 +184,7 @@ "ng-packagr": "^17.0.0", "protractor": "^7.0.0", "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=5.2 <5.4" + "typescript": ">=5.2 <5.5" }, "peerDependenciesMeta": { "@angular/localize": { @@ -232,12 +232,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1702.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1702.1.tgz", - "integrity": "sha512-cmtGn8IYqruHuq1yPYEA17tLDTGmMhDPLagAbjZPVAjTpwCwC28H6sRXyhLTiSpzXdXUgROTO6bSXTvtJyyDSA==", + "version": "0.1703.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.1.tgz", + "integrity": "sha512-nVUzewX8RCzaEPQZ1JQpE42wpsYchKQwfXUSCkoUsuCMB2c6zuEz0Jt94nzJg3UjSEEV4ZqCH8v5MDOvB49Rlw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1702.1", + "@angular-devkit/architect": "0.1703.1", "rxjs": "7.8.1" }, "engines": { @@ -260,9 +260,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.2.1.tgz", - "integrity": "sha512-4jWG7akd5wVxjKkLKDT1zUTyLJeBP5mDmGUPooZ6zVHy39X6htYC+BV3uu/T6gVrD4FyONMDezedpBOrQPtZ6A==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.1.tgz", + "integrity": "sha512-EP7zwqBEaOPuBJwzKmh2abfgNFITGX178BOyTG6zTymeMzEbrvy2OdeQXSslkJ/RGLCpx60GT+0CFW7wGlQR6Q==", "dev": true, "dependencies": { "ajv": "8.12.0", @@ -478,9 +478,9 @@ } }, "node_modules/@angular/animations": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.2.2.tgz", - "integrity": "sha512-ENr35pDVslioJO8zBLo1QClzC7NqTc0Du36UMtWkw3cg+QRLnAZ7zfju5w0O8K7Z3omDtFzgVSPfyS0VDkrXPQ==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.3.1.tgz", + "integrity": "sha512-2TZ0M5J0IizhHpb404DeqArlv8Ki9BFz5ZUuET2uFROpKW8IMDCht8fSrn/DKHpjB9lvzPUhNFaRxNWEY6klnA==", "dependencies": { "tslib": "^2.3.0" }, @@ -488,13 +488,13 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.2.2" + "@angular/core": "17.3.1" } }, "node_modules/@angular/cdk": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.2.1.tgz", - "integrity": "sha512-9cWV9MyWnpImns/WQApgoQBKblXA9Zx2CpCkDNipRgx9RyvGrvCLjpEfwQI4HjpPAQDI1trsbeJKihzgz4tFgw==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.3.1.tgz", + "integrity": "sha512-pHSN+KlCmdo2u9jY7Yxsry/ZK+EcjOYGzdwxXxcKragMzm7etY3BJiTl4N+qZRuV6cJlMj2PRkij8ABi/HQdEA==", "dependencies": { "tslib": "^2.3.0" }, @@ -722,9 +722,9 @@ "dev": true }, "node_modules/@angular/common": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.2.2.tgz", - "integrity": "sha512-F2wQj/lYcZUNZuNmuuDb8RK8tU7e1w7IzN8J6nT2gQHq6NiZfYiUL2XrToGtdd/cZjBeYKGiWRBW/PsZzKyC3A==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.3.1.tgz", + "integrity": "sha512-HyUTJ4RxhE3bOmFRV6Fv2y01ixbrUb8Hd4MxPm8REbNMGKsWCfXhR3FfxFL18Sc03SAF+o0Md0wwekjFKTNKfQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -732,14 +732,14 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.2.2", + "@angular/core": "17.3.1", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.2.2.tgz", - "integrity": "sha512-loRr4+9/JkSDszExZiS+iuhjXj7wvLF4gJeqlbp2PbPl4eUoGKYq0RVZ3a7IkIXxB5sgoYB5MjKsbdm/uaMK1A==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.3.1.tgz", + "integrity": "sha512-8qqlWPGZEyD2FY5losOW3Aocro+lFysPDzsf0LHgQUM6Ub1b+pq4jUOjH6w0vzaxG3TfxkgzOQ9aNdWtSV67Rg==", "dependencies": { "tslib": "^2.3.0" }, @@ -747,7 +747,7 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/core": "17.2.2" + "@angular/core": "17.3.1" }, "peerDependenciesMeta": { "@angular/core": { @@ -756,9 +756,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.2.2.tgz", - "integrity": "sha512-tFfbamdLhn8R30/aKxhXNG6CwelJOpVxfUnTizb7pWUJ/UQ4py0xzJp7s0QzKjR1lpRAq3rPtsE3f9BbcHD1HA==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.3.1.tgz", + "integrity": "sha512-xLV9KU+zOpe57/2rQ59ku21EaStNpLSlR9+qkDYf8JR09fB+W9vY3UYbpi5RjHxAFIZBM5D9SFQjjll8rch26g==", "dev": true, "dependencies": { "@babel/core": "7.23.9", @@ -779,14 +779,59 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/compiler": "17.2.2", - "typescript": ">=5.2 <5.4" + "@angular/compiler": "17.3.1", + "typescript": ">=5.2 <5.5" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", + "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.9", + "@babel/parser": "^7.23.9", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@angular/core": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.2.2.tgz", - "integrity": "sha512-jXnrOVsA9b34PJN383EOss3ejd5+xUTeijuUy5njPRXpxMxrGjV5gkk0lSxsALRxw2ICax2tMoGmHXfXO1x9gw==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.3.1.tgz", + "integrity": "sha512-Qf3/sgkXS1LHwOTtqAVYprySrn0YpPIZqerPc0tK+hyQfwAz5BQlpcBhbH8RWKlfCY8eO0cqo/j0+e8DQOgYfg==", "dependencies": { "tslib": "^2.3.0" }, @@ -799,9 +844,9 @@ } }, "node_modules/@angular/forms": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.2.2.tgz", - "integrity": "sha512-xxy1Khpun2TpSDQch6BK4uHkqIxZvxsBU2LZgo/3W604lKoVjBGKPZqoYFRew2OPeCQ3VjK9P8a8ZhitsLLlKQ==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.3.1.tgz", + "integrity": "sha512-HndsO90k67sFHzd+sII+rhAUksffBvquFuAUCc6QR9WVjILxVg2fY7oBidgS1gKNqu0mptPG0GvuORnaW/0gSg==", "dependencies": { "tslib": "^2.3.0" }, @@ -809,16 +854,16 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.2.2", - "@angular/core": "17.2.2", - "@angular/platform-browser": "17.2.2", + "@angular/common": "17.3.1", + "@angular/core": "17.3.1", + "@angular/platform-browser": "17.3.1", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/material": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-17.2.1.tgz", - "integrity": "sha512-NLQJkX4XiwIm32dGdNseoc+ARn6JvuB2xMY5XfWTtjJBbQaPk5sIvjH4wsAEeYqDKtZbRCjxGwRz0K1djyaVqQ==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-17.3.1.tgz", + "integrity": "sha512-Md1OnO0/sQvK5GkTQyE4v1DAaMswXt1TnjjY07KG7cICTrUN8lc0a2P9dMjlSFXIhxC7PTlNH6plSZ1uspbU8Q==", "dependencies": { "@material/animation": "15.0.0-canary.7f224ddd4.0", "@material/auto-init": "15.0.0-canary.7f224ddd4.0", @@ -871,7 +916,7 @@ }, "peerDependencies": { "@angular/animations": "^17.0.0 || ^18.0.0", - "@angular/cdk": "17.2.1", + "@angular/cdk": "17.3.1", "@angular/common": "^17.0.0 || ^18.0.0", "@angular/core": "^17.0.0 || ^18.0.0", "@angular/forms": "^17.0.0 || ^18.0.0", @@ -880,9 +925,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.2.2.tgz", - "integrity": "sha512-6AZhQfZpo/apiRKwhy6es1RpoxgCXMR4y7Eo7GvVHpMKBwioWwP2H+qg83ed2xv0/GXIyqZsHjpEjsLPE83uyw==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.3.1.tgz", + "integrity": "sha512-8ABAL8PElSGzkIparVwifsU0NSu0DdqnWYw9YvLhhZQ6lOuWbG+dTUo/DXzmWhA6ezQWJGNakEZPJJytFIIy+A==", "dependencies": { "tslib": "^2.3.0" }, @@ -890,9 +935,9 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/animations": "17.2.2", - "@angular/common": "17.2.2", - "@angular/core": "17.2.2" + "@angular/animations": "17.3.1", + "@angular/common": "17.3.1", + "@angular/core": "17.3.1" }, "peerDependenciesMeta": { "@angular/animations": { @@ -901,9 +946,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.2.2.tgz", - "integrity": "sha512-I52zbDSic4LB0yhCFUEBZKg9QkLKVUCGTco0XFHNRy3EF54Jvs0uWBqG79egsuXmyBNQY0E3op9eqhhn6Mnwbw==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.1.tgz", + "integrity": "sha512-ACW/npNaDxUNQtEomjjv/KIBY8jHEinePff5qosnAxLE0IpA4qE9eDp36zG35xoJqrPJPYjXbZCBRqqrzM7U7Q==", "dependencies": { "tslib": "^2.3.0" }, @@ -911,16 +956,16 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.2.2", - "@angular/compiler": "17.2.2", - "@angular/core": "17.2.2", - "@angular/platform-browser": "17.2.2" + "@angular/common": "17.3.1", + "@angular/compiler": "17.3.1", + "@angular/core": "17.3.1", + "@angular/platform-browser": "17.3.1" } }, "node_modules/@angular/router": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.2.2.tgz", - "integrity": "sha512-3mT2+qBF8urFeY6eZVZX5bmAdK9ojJRZi7yB9ocpieE1Jdd/1NYCfIsQxJk032syEGc2NJftijTzuNiflLzlTA==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.3.1.tgz", + "integrity": "sha512-H6H7lY9i5Ppu0SFwwpeWqJbCFw8cILOj8Rd1+AGoCN5m3ivPtjD2Ltz62PI2zZkqx+WhQdk19l61Wm3oRqg70A==", "dependencies": { "tslib": "^2.3.0" }, @@ -928,38 +973,38 @@ "node": "^18.13.0 || >=20.9.0" }, "peerDependencies": { - "@angular/common": "17.2.2", - "@angular/core": "17.2.2", - "@angular/platform-browser": "17.2.2", + "@angular/common": "17.3.1", + "@angular/core": "17.3.1", + "@angular/platform-browser": "17.3.1", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -967,11 +1012,11 @@ "@babel/generator": "^7.23.6", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -1066,9 +1111,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", - "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", + "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -1076,7 +1121,7 @@ "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -1124,9 +1169,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -1186,12 +1231,12 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1229,9 +1274,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1255,13 +1300,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -1308,9 +1353,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1349,37 +1394,38 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", "dev": true, "dependencies": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1389,12 +1435,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "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.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "version": "7.24.1", + "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.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1404,14 +1450,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" + "@babel/plugin-transform-optional-chaining": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1421,13 +1467,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1512,12 +1558,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1527,12 +1573,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1684,12 +1730,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1734,12 +1780,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1749,12 +1795,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", + "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1764,13 +1810,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1780,13 +1826,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", + "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -1797,17 +1843,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, @@ -1819,13 +1865,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1835,12 +1881,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1850,13 +1896,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1866,12 +1912,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1881,12 +1927,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -1897,13 +1943,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", "dev": true, "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1913,12 +1959,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1929,12 +1975,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { @@ -1945,14 +1991,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1962,12 +2008,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1978,12 +2024,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1993,12 +2039,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -2009,12 +2055,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2024,13 +2070,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2040,13 +2086,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-simple-access": "^7.22.5" }, "engines": { @@ -2057,14 +2103,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { @@ -2075,13 +2121,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2107,12 +2153,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2122,12 +2168,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -2138,12 +2184,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -2154,16 +2200,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" + "@babel/plugin-transform-parameters": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -2173,13 +2218,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -2189,12 +2234,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -2205,12 +2250,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -2222,12 +2267,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2237,13 +2282,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2253,14 +2298,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -2271,12 +2316,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2286,12 +2331,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "regenerator-transform": "^0.15.2" }, "engines": { @@ -2302,12 +2347,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2317,13 +2362,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz", - "integrity": "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.0.tgz", + "integrity": "sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "babel-plugin-polyfill-corejs2": "^0.4.8", "babel-plugin-polyfill-corejs3": "^0.9.0", "babel-plugin-polyfill-regenerator": "^0.5.5", @@ -2346,12 +2391,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2361,12 +2406,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { @@ -2377,12 +2422,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2392,12 +2437,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2407,12 +2452,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2422,12 +2467,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2437,13 +2482,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2453,13 +2498,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2469,13 +2514,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -2485,14 +2530,14 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", - "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", @@ -2545,7 +2590,7 @@ "@babel/plugin-transform-new-target": "^7.23.3", "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", "@babel/plugin-transform-object-super": "^7.23.3", "@babel/plugin-transform-optional-catch-binding": "^7.23.4", "@babel/plugin-transform-optional-chaining": "^7.23.4", @@ -2608,9 +2653,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2620,33 +2665,33 @@ } }, "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2654,10 +2699,25 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -2687,9 +2747,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz", - "integrity": "sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", + "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", "cpu": [ "ppc64" ], @@ -2703,9 +2763,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.0.tgz", - "integrity": "sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", + "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", "cpu": [ "arm" ], @@ -2719,9 +2779,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz", - "integrity": "sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", + "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", "cpu": [ "arm64" ], @@ -2735,9 +2795,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.0.tgz", - "integrity": "sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", + "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", "cpu": [ "x64" ], @@ -2751,9 +2811,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz", - "integrity": "sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", + "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", "cpu": [ "arm64" ], @@ -2767,9 +2827,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.0.tgz", - "integrity": "sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", + "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", "cpu": [ "x64" ], @@ -2783,9 +2843,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.0.tgz", - "integrity": "sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", + "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", "cpu": [ "arm64" ], @@ -2799,9 +2859,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.0.tgz", - "integrity": "sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", + "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", "cpu": [ "x64" ], @@ -2815,9 +2875,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.0.tgz", - "integrity": "sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", + "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", "cpu": [ "arm" ], @@ -2831,9 +2891,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.0.tgz", - "integrity": "sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", + "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", "cpu": [ "arm64" ], @@ -2847,9 +2907,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.0.tgz", - "integrity": "sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", + "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", "cpu": [ "ia32" ], @@ -2863,9 +2923,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.0.tgz", - "integrity": "sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", + "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", "cpu": [ "loong64" ], @@ -2879,9 +2939,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.0.tgz", - "integrity": "sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", + "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", "cpu": [ "mips64el" ], @@ -2895,9 +2955,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.0.tgz", - "integrity": "sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", + "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", "cpu": [ "ppc64" ], @@ -2911,9 +2971,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.0.tgz", - "integrity": "sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", + "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", "cpu": [ "riscv64" ], @@ -2927,9 +2987,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.0.tgz", - "integrity": "sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", + "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", "cpu": [ "s390x" ], @@ -2943,9 +3003,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.0.tgz", - "integrity": "sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz", + "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==", "cpu": [ "x64" ], @@ -2959,9 +3019,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.0.tgz", - "integrity": "sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", + "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", "cpu": [ "x64" ], @@ -2975,9 +3035,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.0.tgz", - "integrity": "sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", + "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", "cpu": [ "x64" ], @@ -2991,9 +3051,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.0.tgz", - "integrity": "sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", + "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", "cpu": [ "x64" ], @@ -3007,9 +3067,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.0.tgz", - "integrity": "sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", + "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", "cpu": [ "arm64" ], @@ -3023,9 +3083,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.0.tgz", - "integrity": "sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", + "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", "cpu": [ "ia32" ], @@ -3039,9 +3099,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.0.tgz", - "integrity": "sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", + "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", "cpu": [ "x64" ], @@ -3177,15 +3237,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -3353,14 +3404,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz", - "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -3376,22 +3427,22 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { @@ -3401,9 +3452,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz", - "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3417,12 +3468,12 @@ "dev": true }, "node_modules/@ljharb/through": { - "version": "2.3.12", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz", - "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==", + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", + "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -4181,9 +4232,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.2.1.tgz", - "integrity": "sha512-5O493oqZw0os1Gj3otVTcIXS3nGs60eXZ9w3vsK5w7tZ5x6XqZvO00X8WZQhcxXA9HMG4iDCsU2ll3lcYZVxmg==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.1.tgz", + "integrity": "sha512-6qRYFN6DqogZK0ZFrSlhg1OsIWm3lL3m+/Ixoj6/MLLjDBrTtHqmI93vg6P1EKYTH4fWChL7jtv7iS/LSZubgw==", "dev": true, "engines": { "node": "^18.13.0 || >=20.9.0", @@ -4192,7 +4243,7 @@ }, "peerDependencies": { "@angular/compiler-cli": "^17.0.0", - "typescript": ">=5.2 <5.4", + "typescript": ">=5.2 <5.5", "webpack": "^5.54.0" } }, @@ -4729,9 +4780,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz", - "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", "cpu": [ "arm" ], @@ -4742,9 +4793,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz", - "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", "cpu": [ "arm64" ], @@ -4755,9 +4806,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz", - "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", "cpu": [ "arm64" ], @@ -4768,9 +4819,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz", - "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", "cpu": [ "x64" ], @@ -4781,9 +4832,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz", - "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", "cpu": [ "arm" ], @@ -4794,9 +4845,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz", - "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", "cpu": [ "arm64" ], @@ -4807,9 +4858,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz", - "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", "cpu": [ "arm64" ], @@ -4820,9 +4871,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz", - "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", "cpu": [ "riscv64" ], @@ -4833,9 +4884,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz", - "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", "cpu": [ "x64" ], @@ -4846,9 +4897,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz", - "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", "cpu": [ "x64" ], @@ -4859,9 +4910,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz", - "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", "cpu": [ "arm64" ], @@ -4872,9 +4923,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz", - "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", "cpu": [ "ia32" ], @@ -4885,9 +4936,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz", - "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", "cpu": [ "x64" ], @@ -5151,9 +5202,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.3", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.3.tgz", - "integrity": "sha512-PvSf1wfv2wJpVIFUMSb+i4PvqNYkB9Rkp9ZDO3oaWzq4SKhsQk4mrMBr3ZH06I0hKrVGLBacmgl8JM4WVjb9dg==", + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", "dev": true, "dependencies": { "@types/estree": "*", @@ -5234,9 +5285,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.19.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.18.tgz", - "integrity": "sha512-80CP7B8y4PzZF0GWx15/gVWRrB5y/bIjNI84NK3cmQJu0WZwvmj2WMA5LcofQFVfLqqCSp545+U2LsrVzX36Zg==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -5252,9 +5303,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", "dev": true }, "node_modules/@types/range-parser": { @@ -5735,9 +5786,9 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -5757,9 +5808,9 @@ "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { @@ -5780,15 +5831,15 @@ "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { @@ -5816,28 +5867,28 @@ "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "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==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "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" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", @@ -5845,24 +5896,24 @@ } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", @@ -5871,12 +5922,12 @@ } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -6206,9 +6257,9 @@ "dev": true }, "node_modules/autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "version": "10.4.18", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", + "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", "dev": true, "funding": [ { @@ -6225,8 +6276,8 @@ } ], "dependencies": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001591", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -6243,12 +6294,12 @@ } }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -6296,13 +6347,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.5.0", + "@babel/helper-define-polyfill-provider": "^0.6.1", "semver": "^6.3.1" }, "peerDependencies": { @@ -6331,6 +6382,22 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", @@ -6343,6 +6410,22 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/babel-plugin-polyfill-regenerator/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -6394,12 +6477,15 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bl": { @@ -6686,9 +6772,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001591", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz", - "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==", + "version": "1.0.30001599", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz", + "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==", "dev": true, "funding": [ { @@ -7280,12 +7366,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", - "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "dev": true, "dependencies": { - "browserslist": "^4.22.3" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -7356,9 +7442,9 @@ } }, "node_modules/critters": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", - "integrity": "sha512-CImNRorKOl5d8TWcnAz5n5izQ6HFsvz29k327/ELy6UFcmbiZNOsinaKvzv16WZR0P6etfSWYzE47C4/56B3Uw==", + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.22.tgz", + "integrity": "sha512-NU7DEcQZM2Dy8XTKFHxtdnIM/drE312j2T4PCVaSUcS0oBeyT/NImpRw/Ap0zOr/1SE7SgPK9tGPg1WK/sVakw==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -7367,7 +7453,7 @@ "domhandler": "^5.0.2", "htmlparser2": "^8.0.2", "postcss": "^8.4.23", - "pretty-bytes": "^5.3.0" + "postcss-media-query-parser": "^0.2.3" } }, "node_modules/critters/node_modules/ansi-styles": { @@ -7849,9 +7935,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.682", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz", - "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==", + "version": "1.4.713", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.713.tgz", + "integrity": "sha512-vDarADhwntXiULEdmWd77g2dV6FrNGa8ecAC29MZ4TwPut2fvosD0/5sJd1qWNNe8HcJFAC+F5Lf9jW1NPtWmw==", "dev": true }, "node_modules/emoji-regex": { @@ -7941,9 +8027,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", - "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -8042,15 +8128,15 @@ } }, "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.2.tgz", + "integrity": "sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw==", "dev": true }, "node_modules/esbuild": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.0.tgz", - "integrity": "sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", + "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", "dev": true, "hasInstallScript": true, "optional": true, @@ -8061,35 +8147,35 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.0", - "@esbuild/android-arm": "0.20.0", - "@esbuild/android-arm64": "0.20.0", - "@esbuild/android-x64": "0.20.0", - "@esbuild/darwin-arm64": "0.20.0", - "@esbuild/darwin-x64": "0.20.0", - "@esbuild/freebsd-arm64": "0.20.0", - "@esbuild/freebsd-x64": "0.20.0", - "@esbuild/linux-arm": "0.20.0", - "@esbuild/linux-arm64": "0.20.0", - "@esbuild/linux-ia32": "0.20.0", - "@esbuild/linux-loong64": "0.20.0", - "@esbuild/linux-mips64el": "0.20.0", - "@esbuild/linux-ppc64": "0.20.0", - "@esbuild/linux-riscv64": "0.20.0", - "@esbuild/linux-s390x": "0.20.0", - "@esbuild/linux-x64": "0.20.0", - "@esbuild/netbsd-x64": "0.20.0", - "@esbuild/openbsd-x64": "0.20.0", - "@esbuild/sunos-x64": "0.20.0", - "@esbuild/win32-arm64": "0.20.0", - "@esbuild/win32-ia32": "0.20.0", - "@esbuild/win32-x64": "0.20.0" + "@esbuild/aix-ppc64": "0.20.1", + "@esbuild/android-arm": "0.20.1", + "@esbuild/android-arm64": "0.20.1", + "@esbuild/android-x64": "0.20.1", + "@esbuild/darwin-arm64": "0.20.1", + "@esbuild/darwin-x64": "0.20.1", + "@esbuild/freebsd-arm64": "0.20.1", + "@esbuild/freebsd-x64": "0.20.1", + "@esbuild/linux-arm": "0.20.1", + "@esbuild/linux-arm64": "0.20.1", + "@esbuild/linux-ia32": "0.20.1", + "@esbuild/linux-loong64": "0.20.1", + "@esbuild/linux-mips64el": "0.20.1", + "@esbuild/linux-ppc64": "0.20.1", + "@esbuild/linux-riscv64": "0.20.1", + "@esbuild/linux-s390x": "0.20.1", + "@esbuild/linux-x64": "0.20.1", + "@esbuild/netbsd-x64": "0.20.1", + "@esbuild/openbsd-x64": "0.20.1", + "@esbuild/sunos-x64": "0.20.1", + "@esbuild/win32-arm64": "0.20.1", + "@esbuild/win32-ia32": "0.20.1", + "@esbuild/win32-x64": "0.20.1" } }, "node_modules/esbuild-wasm": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.20.0.tgz", - "integrity": "sha512-Lc9KeQCg1Zf8kCtfDXgy29rx0x8dOuhDWbkP76Wc64q7ctOOc1Zv1C39AxiE+y4N6ONyXtJk4HKpM7jlU7/jSA==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.20.1.tgz", + "integrity": "sha512-6v/WJubRsjxBbQdz6izgvx7LsVFvVaGmSdwrFHmEzoVgfXL89hkKPoQHsnVI2ngOkcBUQT9kmAM1hVL1k/Av4A==", "dev": true, "bin": { "esbuild": "bin/esbuild" @@ -8553,17 +8639,17 @@ "dev": true }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.1.tgz", + "integrity": "sha512-K4w1/Bp7y8iSiVObmCrtq8Cs79XjJc/RU2YYkZQ7wpUu5ZyZ7MtPHkqoMz4pf+mgXfNvo2qft8D9OnrH2ABk9w==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -8594,34 +8680,10 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { "node": ">= 0.6" @@ -8660,21 +8722,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -9304,9 +9351,9 @@ } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -9379,9 +9426,9 @@ } }, "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", "dev": true, "funding": [ { @@ -9514,9 +9561,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -9712,9 +9759,9 @@ } }, "node_modules/inquirer": { - "version": "9.2.14", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.14.tgz", - "integrity": "sha512-4ByIMt677Iz5AvjyKrDpzaepIyMewNvDcvwpVVRZNmy9dLakVoVgdCHZXbK1SlVJra1db0JZ6XkJyHsanpdrdQ==", + "version": "9.2.15", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", + "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", "dev": true, "dependencies": { "@ljharb/through": "^2.3.12", @@ -10991,9 +11038,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -11158,9 +11205,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", - "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", + "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", "dev": true, "dependencies": { "schema-utils": "^4.0.0", @@ -12567,9 +12614,9 @@ } }, "node_modules/piscina": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.3.1.tgz", - "integrity": "sha512-MBj0QYm3hJQ/C/wIXTN1OCYC8uQ4BBJ4LVele2P4ZwVQAH04vkk8E1SpDbuemLAL1dZorbuOob9rYqJeWCcCRg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.4.0.tgz", + "integrity": "sha512-+AQduEJefrOApE4bV7KRmp3N2JnnyErlVqq4P/jmko4FPz9Z877BCccl/iB3FdrWSUkvbGV9Kan/KllJgat3Vg==", "dev": true, "optionalDependencies": { "nice-napi": "^1.0.2" @@ -12701,9 +12748,9 @@ } }, "node_modules/postcss-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.0.tgz", - "integrity": "sha512-AbperNcX3rlob7Ay7A/HQcrofug1caABBkopoFeOQMspZBqcqj6giYn1Bwey/0uiOPAcR+NQD0I2HC7rXzk91w==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", "dev": true, "dependencies": { "cosmiconfig": "^9.0.0", @@ -12731,6 +12778,12 @@ } } }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, "node_modules/postcss-modules-extract-imports": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", @@ -12791,9 +12844,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -12833,18 +12886,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -13370,9 +13411,9 @@ } }, "node_modules/rollup": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz", - "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -13385,19 +13426,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.12.0", - "@rollup/rollup-android-arm64": "4.12.0", - "@rollup/rollup-darwin-arm64": "4.12.0", - "@rollup/rollup-darwin-x64": "4.12.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.12.0", - "@rollup/rollup-linux-arm64-gnu": "4.12.0", - "@rollup/rollup-linux-arm64-musl": "4.12.0", - "@rollup/rollup-linux-riscv64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-gnu": "4.12.0", - "@rollup/rollup-linux-x64-musl": "4.12.0", - "@rollup/rollup-win32-arm64-msvc": "4.12.0", - "@rollup/rollup-win32-ia32-msvc": "4.12.0", - "@rollup/rollup-win32-x64-msvc": "4.12.0", + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", "fsevents": "~2.3.2" } }, @@ -13473,9 +13514,9 @@ "integrity": "sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw==" }, "node_modules/sass": { - "version": "1.70.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz", - "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==", + "version": "1.71.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", + "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -13490,9 +13531,9 @@ } }, "node_modules/sass-loader": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.0.tgz", - "integrity": "sha512-LS2mLeFWA+orYxHNu+O18Xe4jR0kyamNOOUsE3NyBP4DvIL+8stHpNX0arYTItdPe80kluIiJ7Wfe/9iHSRO0Q==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.1.tgz", + "integrity": "sha512-QX8AasDg75monlybel38BZ49JP5Z+uSKfKwF2rO7S74BywaRmGQMUBw9dtkS+ekyM/QnP+NOrRYq8ABMZ9G8jw==", "dev": true, "dependencies": { "neo-async": "^2.6.2" @@ -13767,17 +13808,17 @@ } }, "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "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, "dependencies": { - "define-data-property": "^1.1.2", + "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -13832,12 +13873,12 @@ } }, "node_modules/side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", "object-inspect": "^1.13.1" @@ -13892,9 +13933,9 @@ } }, "node_modules/socket.io": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.4.tgz", - "integrity": "sha512-DcotgfP1Zg9iP/dH9zvAQcWrE0TtbMVwXmlV4T4mqsvY+gw+LqUGPfx2AoVyRk0FLME+GQhufDMyacFmw7ksqw==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", "dev": true, "dependencies": { "accepts": "~1.3.4", @@ -13981,9 +14022,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -14418,9 +14459,9 @@ "dev": true }, "node_modules/terser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", - "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", + "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -14602,9 +14643,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", - "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { "node": ">=16" @@ -14747,13 +14788,10 @@ } }, "node_modules/undici": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.6.2.tgz", - "integrity": "sha512-vSqvUE5skSxQJ5sztTZ/CdeJb1Wq0Hf44hlYMciqHghvz+K88U0l7D6u1VsndoFgskDcnU+nG3gYmMzJVzd9Qg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.7.1.tgz", + "integrity": "sha512-+Wtb9bAQw6HYWzCnxrPTMVEV3Q1QjYanI0E4q02ehReMuquQdLTEFEYbfs7hcImVYKcQkWSwT6buEmSVIiDDtQ==", "dev": true, - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, "engines": { "node": ">=18.0" } @@ -14947,13 +14985,13 @@ } }, "node_modules/vite": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz", - "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz", + "integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==", "dev": true, "dependencies": { "esbuild": "^0.19.3", - "postcss": "^8.4.32", + "postcss": "^8.4.35", "rollup": "^4.2.0" }, "bin": { @@ -15448,9 +15486,9 @@ } }, "node_modules/webpack": { - "version": "5.90.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz", - "integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -15582,9 +15620,9 @@ } }, "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dev": true, "dependencies": { "colorette": "^2.0.10", diff --git a/console-webapp/src/app/app-routing.module.ts b/console-webapp/src/app/app-routing.module.ts index 62eca80f8..3b0265666 100644 --- a/console-webapp/src/app/app-routing.module.ts +++ b/console-webapp/src/app/app-routing.module.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,69 +13,106 @@ // limitations under the License. import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { TldsComponent } from './tlds/tlds.component'; -import { HomeComponent } from './home/home.component'; -import { SettingsComponent } from './settings/settings.component'; -import SettingsContactComponent from './settings/contact/contact.component'; -import SettingsWhoisComponent from './settings/whois/whois.component'; -import SettingsUsersComponent from './settings/users/users.component'; -import SettingsSecurityComponent from './settings/security/security.component'; -import { RegistrarGuard } from './registrar/registrar.guard'; -import { RegistrarComponent } from './registrar/registrarsTable.component'; -import { EmptyRegistrar } from './registrar/emptyRegistrar.component'; -import ContactComponent from './settings/contact/contact.component'; -import WhoisComponent from './settings/whois/whois.component'; -import SecurityComponent from './settings/security/security.component'; -import UsersComponent from './settings/users/users.component'; +import { Route, RouterModule } from '@angular/router'; +import { BillingInfoComponent } from './billingInfo/billingInfo.component'; import { DomainListComponent } from './domains/domainList.component'; +import { HomeComponent } from './home/home.component'; +import { RegistrarDetailsComponent } from './registrar/registrarDetails.component'; +import { RegistrarComponent } from './registrar/registrarsTable.component'; +import { ResourcesComponent } from './resources/resources.component'; +import ContactComponent from './settings/contact/contact.component'; +import SecurityComponent from './settings/security/security.component'; +import { SettingsComponent } from './settings/settings.component'; +import UsersComponent from './settings/users/users.component'; +import WhoisComponent from './settings/whois/whois.component'; +import { SupportComponent } from './support/support.component'; -const routes: Routes = [ +export interface RouteWithIcon extends Route { + iconName?: string; +} + +export const routes: RouteWithIcon[] = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'registrars', component: RegistrarComponent }, - { path: 'empty-registrar', component: EmptyRegistrar }, - { path: 'home', component: HomeComponent, canActivate: [RegistrarGuard] }, - { path: 'tlds', component: TldsComponent, canActivate: [RegistrarGuard] }, + { + path: 'home', + component: HomeComponent, + title: 'Dashboard', + iconName: 'view_comfy_alt', + }, + // { path: 'tlds', component: TldsComponent, title: "TLDs", iconName: "event_list" }, { path: DomainListComponent.PATH, component: DomainListComponent, - canActivate: [RegistrarGuard], + title: 'Domains', + iconName: 'view_list', }, { path: SettingsComponent.PATH, component: SettingsComponent, + title: 'Settings', + iconName: 'settings', children: [ { path: '', - redirectTo: 'registrars', + redirectTo: ContactComponent.PATH, pathMatch: 'full', }, { path: ContactComponent.PATH, - component: SettingsContactComponent, - canActivate: [RegistrarGuard], + component: ContactComponent, + title: 'Contacts', }, { path: WhoisComponent.PATH, - component: SettingsWhoisComponent, - canActivate: [RegistrarGuard], + component: WhoisComponent, + title: 'WHOIS Info', }, { path: SecurityComponent.PATH, - component: SettingsSecurityComponent, - canActivate: [RegistrarGuard], + component: SecurityComponent, + title: 'Security', }, { path: UsersComponent.PATH, - component: SettingsUsersComponent, - canActivate: [RegistrarGuard], - }, - { - path: RegistrarComponent.PATH, - component: RegistrarComponent, + component: UsersComponent, }, ], }, + // { + // path: EppConsole.PATH, + // component: EppConsoleComponent, + // title: "EPP Console", + // iconName: "upgrade" + // }, + { + path: RegistrarComponent.PATH, + component: RegistrarComponent, + title: 'Registrars', + iconName: 'account_circle', + }, + { + path: RegistrarDetailsComponent.PATH, + component: RegistrarDetailsComponent, + }, + { + path: BillingInfoComponent.PATH, + component: BillingInfoComponent, + title: 'Billing Info', + iconName: 'credit_card', + }, + { + path: ResourcesComponent.PATH, + component: ResourcesComponent, + title: 'Resources', + iconName: 'description', + }, + { + path: SupportComponent.PATH, + component: SupportComponent, + title: 'Support', + iconName: 'help', + }, ]; @NgModule({ diff --git a/console-webapp/src/app/app.component.html b/console-webapp/src/app/app.component.html index db688b2dd..5334de308 100644 --- a/console-webapp/src/app/app.component.html +++ b/console-webapp/src/app/app.component.html @@ -1,24 +1,19 @@ -
- +
+ - - - - Home page - - - TLDS - - - Settings - - + +
-
+
diff --git a/console-webapp/src/app/app.component.scss b/console-webapp/src/app/app.component.scss index a3a6b7ec6..642dfc5f8 100644 --- a/console-webapp/src/app/app.component.scss +++ b/console-webapp/src/app/app.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ // limitations under the License. :host { - font-family: Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", - "Segoe UI Emoji", "Segoe UI Symbol" !important; + font-family: "Google Sans", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important; font-size: 14px; color: #333; box-sizing: border-box; @@ -26,26 +26,18 @@ display: flex; flex-direction: column; height: 100%; + background: #fff; &__container { flex: 1; - margin-top: -12px; padding-bottom: 36px; + background: transparent; } &__sidebar { - min-width: 300px; - a::before { - background-color: transparent; - } - .active { - background-color: var(--secondary); - } - } - &__content-wrapper { - margin: 12px 24px; + min-width: 240px; + border: 0; } &__content { - max-width: 1340px; - margin: 0 auto; + padding: 0 16px; } &__global-spinner { margin-bottom: 2rem; diff --git a/console-webapp/src/app/app.component.spec.ts b/console-webapp/src/app/app.component.spec.ts index 8ac87543a..55f9248cf 100644 --- a/console-webapp/src/app/app.component.spec.ts +++ b/console-webapp/src/app/app.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/app.component.ts b/console-webapp/src/app/app.component.ts index 4c69f91f2..6531fe73f 100644 --- a/console-webapp/src/app/app.component.ts +++ b/console-webapp/src/app/app.component.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { AfterViewInit, Component, ViewChild, effect } from '@angular/core'; -import { RegistrarService } from './registrar/registrar.service'; -import { UserDataService } from './shared/services/userData.service'; -import { GlobalLoaderService } from './shared/services/globalLoader.service'; -import { NavigationEnd, Router } from '@angular/router'; +import { AfterViewInit, Component, ViewChild } from '@angular/core'; import { MatSidenav } from '@angular/material/sidenav'; +import { NavigationEnd, Router } from '@angular/router'; +import { RegistrarService } from './registrar/registrar.service'; +import { BreakPointObserverService } from './shared/services/breakPoint.service'; +import { GlobalLoaderService } from './shared/services/globalLoader.service'; +import { UserDataService } from './shared/services/userData.service'; @Component({ selector: 'app-root', @@ -25,32 +26,32 @@ import { MatSidenav } from '@angular/material/sidenav'; styleUrls: ['./app.component.scss'], }) export class AppComponent implements AfterViewInit { - renderRouter: boolean = true; - - @ViewChild('sidenav') + @ViewChild(MatSidenav) sidenav!: MatSidenav; constructor( protected registrarService: RegistrarService, protected userDataService: UserDataService, protected globalLoader: GlobalLoaderService, - protected router: Router - ) { - effect(() => { - if (registrarService.registrarId()) { - this.renderRouter = false; - setTimeout(() => { - this.renderRouter = true; - }, 400); - } - }); - } + protected breakpointObserver: BreakPointObserverService, + private router: Router + ) {} ngAfterViewInit() { this.router.events.subscribe((event) => { if (event instanceof NavigationEnd) { - this.sidenav.close(); + if (this.breakpointObserver.isMobileView()) { + this.sidenav.close(); + } } }); } + + toggleSidenav() { + if (this.sidenav.opened) { + this.sidenav.close(); + } else { + this.sidenav.open(); + } + } } diff --git a/console-webapp/src/app/app.module.ts b/console-webapp/src/app/app.module.ts index 83aac71a2..7e8c7848e 100644 --- a/console-webapp/src/app/app.module.ts +++ b/console-webapp/src/app/app.module.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,71 +13,68 @@ // limitations under the License. import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MaterialModule } from './material.module'; import { BackendService } from './shared/services/backend.service'; -import { HomeComponent } from './home/home.component'; -import { TldsComponent } from './tlds/tlds.component'; -import { HeaderComponent } from './header/header.component'; -import { SettingsComponent } from './settings/settings.component'; -import SettingsContactComponent, { - ContactDetailsDialogComponent, -} from './settings/contact/contact.component'; import { HttpClientModule } from '@angular/common/http'; -import { RegistrarComponent } from './registrar/registrarsTable.component'; -import { RegistrarGuard } from './registrar/registrar.guard'; -import SecurityComponent from './settings/security/security.component'; import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field'; -import { EmptyRegistrar } from './registrar/emptyRegistrar.component'; -import { RegistrarSelectorComponent } from './registrar/registrarSelector.component'; -import { GlobalLoaderService } from './shared/services/globalLoader.service'; -import { ContactWidgetComponent } from './home/widgets/contactWidget.component'; -import { PromotionsWidgetComponent } from './home/widgets/promotionsWidget.component'; -import { TldsWidgetComponent } from './home/widgets/tldsWidget.component'; -import { ResourcesWidgetComponent } from './home/widgets/resourcesWidget.component'; -import { EppWidgetComponent } from './home/widgets/eppWidget.component'; -import { BillingWidgetComponent } from './home/widgets/billingWidget.component'; -import { DomainsWidgetComponent } from './home/widgets/domainsWidget.component'; -import { SettingsWidgetComponent } from './home/widgets/settingsWidget.component'; -import { UserDataService } from './shared/services/userData.service'; -import WhoisComponent from './settings/whois/whois.component'; -import { SnackBarModule } from './snackbar.module'; -import { RegistrarDetailsComponent } from './registrar/registrarDetails.component'; +import { BillingInfoComponent } from './billingInfo/billingInfo.component'; import { DomainListComponent } from './domains/domainList.component'; -import { DialogBottomSheetWrapper } from './shared/components/dialogBottomSheet.component'; +import { HeaderComponent } from './header/header.component'; +import { HomeComponent } from './home/home.component'; +import { NavigationComponent } from './navigation/navigation.component'; +import { RegistrarDetailsComponent } from './registrar/registrarDetails.component'; +import { RegistrarSelectorComponent } from './registrar/registrarSelector.component'; +import { RegistrarComponent } from './registrar/registrarsTable.component'; +import { ResourcesComponent } from './resources/resources.component'; +import SettingsContactComponent from './settings/contact/contact.component'; +import { ContactDetailsComponent } from './settings/contact/contactDetails.component'; +import SecurityComponent from './settings/security/security.component'; +import SecurityEditComponent from './settings/security/securityEdit.component'; +import { SettingsComponent } from './settings/settings.component'; +import WhoisComponent from './settings/whois/whois.component'; +import WhoisEditComponent from './settings/whois/whoisEdit.component'; +import { NotificationsComponent } from './shared/components/notifications/notifications.component'; +import { SelectedRegistrarWrapper } from './shared/components/selectedRegistrarWrapper/selectedRegistrarWrapper.component'; +import { LocationBackDirective } from './shared/directives/locationBack.directive'; +import { BreakPointObserverService } from './shared/services/breakPoint.service'; +import { GlobalLoaderService } from './shared/services/globalLoader.service'; +import { UserDataService } from './shared/services/userData.service'; +import { SnackBarModule } from './snackbar.module'; +import { SupportComponent } from './support/support.component'; +import { TldsComponent } from './tlds/tlds.component'; @NgModule({ declarations: [ AppComponent, - DialogBottomSheetWrapper, - BillingWidgetComponent, - ContactDetailsDialogComponent, - ContactWidgetComponent, + BillingInfoComponent, + ContactDetailsComponent, DomainListComponent, - DomainsWidgetComponent, - EmptyRegistrar, - EppWidgetComponent, HeaderComponent, HomeComponent, - PromotionsWidgetComponent, + LocationBackDirective, + NavigationComponent, + NotificationsComponent, RegistrarComponent, RegistrarDetailsComponent, RegistrarSelectorComponent, - ResourcesWidgetComponent, + ResourcesComponent, SecurityComponent, + SecurityEditComponent, + SelectedRegistrarWrapper, SettingsComponent, SettingsContactComponent, - SettingsWidgetComponent, + SupportComponent, TldsComponent, - TldsWidgetComponent, WhoisComponent, + WhoisEditComponent, ], imports: [ AppRoutingModule, @@ -90,8 +87,8 @@ import { DialogBottomSheetWrapper } from './shared/components/dialogBottomSheet. ], providers: [ BackendService, + BreakPointObserverService, GlobalLoaderService, - RegistrarGuard, UserDataService, { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, diff --git a/console-webapp/src/app/billingInfo/billingInfo.component.html b/console-webapp/src/app/billingInfo/billingInfo.component.html new file mode 100644 index 000000000..210ae2c28 --- /dev/null +++ b/console-webapp/src/app/billingInfo/billingInfo.component.html @@ -0,0 +1,16 @@ + +

Billing Info

+
+
+
+ Billing records and information +
+ View on Google Drive +
+
+ +
+
+
diff --git a/console-webapp/src/app/billingInfo/billingInfo.component.scss b/console-webapp/src/app/billingInfo/billingInfo.component.scss new file mode 100644 index 000000000..4cae50e57 --- /dev/null +++ b/console-webapp/src/app/billingInfo/billingInfo.component.scss @@ -0,0 +1,22 @@ +.console-app__billing { + display: flex; + flex-wrap: wrap-reverse; + > div { + flex: 1; + display: flex; + justify-content: center; + flex-direction: column; + text-align: left; + max-width: 300px; + min-width: 200px; + margin-top: -40px; + } + img { + aspect-ratio: 1 / 1; + width: 100%; + } + &-subhead { + font-size: 20px; + margin-bottom: 20px; + } +} diff --git a/console-webapp/src/app/home/widgets/billingWidget.component.ts b/console-webapp/src/app/billingInfo/billingInfo.component.ts similarity index 66% rename from console-webapp/src/app/home/widgets/billingWidget.component.ts rename to console-webapp/src/app/billingInfo/billingInfo.component.ts index 23682bcc0..b3bb8f01e 100644 --- a/console-webapp/src/app/home/widgets/billingWidget.component.ts +++ b/console-webapp/src/app/billingInfo/billingInfo.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,27 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component } from '@angular/core'; -import { RegistrarService } from 'src/app/registrar/registrar.service'; +import { Component, computed } from '@angular/core'; +import { RegistrarService } from '../registrar/registrar.service'; @Component({ - selector: '[app-billing-widget]', - templateUrl: './billingWidget.component.html', + selector: 'app-billingInfo', + templateUrl: './billingInfo.component.html', + styleUrls: ['./billingInfo.component.scss'], }) -export class BillingWidgetComponent { +export class BillingInfoComponent { + public static PATH = 'billingInfo'; constructor(public registrarService: RegistrarService) {} - public get driveFolderUrl(): string { + driveFolderUrl = computed(() => { if (this.registrarService.registrar()?.driveFolderId) { return `https://drive.google.com/drive/folders/${ this.registrarService.registrar()?.driveFolderId }`; } return ''; - } + }); openBillingDetails(e: MouseEvent) { - if (!this.driveFolderUrl) { + if (!this.driveFolderUrl()) { e.preventDefault(); } } diff --git a/console-webapp/src/app/domains/domainList.component.html b/console-webapp/src/app/domains/domainList.component.html index f2cd6b95f..1b3893a05 100644 --- a/console-webapp/src/app/domains/domainList.component.html +++ b/console-webapp/src/app/domains/domainList.component.html @@ -1,52 +1,65 @@ -
- - Filter - - - -
+ +

Domains

+
+ @if (totalResults === 0) { +
+

+ apps_outage +

+

No domains found

+
+ } @else if(isLoading) { -
- - + } @else { + + Filter + + + - - + Domain Name + {{ element.domainName }} - - + - - + - - + Statuses + {{ element.statuses }} - - + + - - - -
Domain Name{{ element.domainName }} Creation Time + Creation Time + {{ element.creationTime.creationTime }} - Expiration Time + Expiration Time + {{ element.registrationExpirationTime }} - Statuses{{ element.statuses }}
No domains found
+ + No domains found + + -
-
+ } +
+ diff --git a/console-webapp/src/app/domains/domainList.component.scss b/console-webapp/src/app/domains/domainList.component.scss index e69de29bb..6c83d51d2 100644 --- a/console-webapp/src/app/domains/domainList.component.scss +++ b/console-webapp/src/app/domains/domainList.component.scss @@ -0,0 +1,32 @@ +.console-app { + $min-width: 756px; + + &__empty-domains { + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + &-icon { + transform: scale(3); + margin-bottom: 0.5rem; + } + } + + &__domains { + width: 100%; + overflow: auto; + } + + &__domains-filter { + min-width: $min-width !important; + width: 100%; + } + + &__domains-table { + min-width: $min-width !important; + } + + .mat-mdc-paginator { + min-width: $min-width !important; + } +} diff --git a/console-webapp/src/app/domains/domainList.component.spec.ts b/console-webapp/src/app/domains/domainList.component.spec.ts index 3dfd85780..3852a5676 100644 --- a/console-webapp/src/app/domains/domainList.component.spec.ts +++ b/console-webapp/src/app/domains/domainList.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/domains/domainList.component.ts b/console-webapp/src/app/domains/domainList.component.ts index c6557e539..7a1424724 100644 --- a/console-webapp/src/app/domains/domainList.component.ts +++ b/console-webapp/src/app/domains/domainList.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,13 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, ViewChild } from '@angular/core'; -import { MatTableDataSource } from '@angular/material/table'; -import { BackendService } from '../shared/services/backend.service'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, ViewChild, effect } from '@angular/core'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { RegistrarService } from '../registrar/registrar.service'; -import { Domain, DomainListService } from './domainList.service'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { MatTableDataSource } from '@angular/material/table'; import { Subject, debounceTime } from 'rxjs'; +import { RegistrarService } from '../registrar/registrar.service'; +import { BackendService } from '../shared/services/backend.service'; +import { Domain, DomainListService } from './domainList.service'; @Component({ selector: 'app-domain-list', @@ -45,15 +47,22 @@ export class DomainListComponent { pageNumber?: number; resultsPerPage = 50; - totalResults?: number; + totalResults?: number = 0; @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator; constructor( private backendService: BackendService, private domainListService: DomainListService, - private registrarService: RegistrarService - ) {} + private registrarService: RegistrarService, + private _snackBar: MatSnackBar + ) { + effect(() => { + if (this.registrarService.registrarId()) { + this.reloadData(); + } + }); + } ngOnInit() { this.dataSource.paginator = this.paginator; @@ -63,7 +72,6 @@ export class DomainListComponent { .subscribe((searchTermValue) => { this.reloadData(); }); - this.reloadData(); } ngOnDestroy() { @@ -79,10 +87,16 @@ export class DomainListComponent { this.totalResults, this.searchTerm ) - .subscribe((domainListResult) => { - this.dataSource.data = domainListResult.domains; - this.totalResults = domainListResult.totalResults; - this.isLoading = false; + .subscribe({ + error: (err: HttpErrorResponse) => { + this._snackBar.open(err.message); + this.isLoading = false; + }, + next: (domainListResult) => { + this.dataSource.data = (domainListResult || {}).domains; + this.totalResults = (domainListResult || {}).totalResults || 0; + this.isLoading = false; + }, }); } diff --git a/console-webapp/src/app/domains/domainList.service.ts b/console-webapp/src/app/domains/domainList.service.ts index 6a53f1504..93651a3a7 100644 --- a/console-webapp/src/app/domains/domainList.service.ts +++ b/console-webapp/src/app/domains/domainList.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,9 +13,9 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { BackendService } from '../shared/services/backend.service'; -import { RegistrarService } from '../registrar/registrar.service'; import { tap } from 'rxjs'; +import { RegistrarService } from '../registrar/registrar.service'; +import { BackendService } from '../shared/services/backend.service'; export interface CreateAutoTimestamp { creationTime: string; @@ -61,7 +61,7 @@ export class DomainListService { ) .pipe( tap((domainListResult: DomainListResult) => { - this.checkpointTime = domainListResult.checkpointTime; + this.checkpointTime = domainListResult?.checkpointTime; }) ); } diff --git a/console-webapp/src/app/header/header.component.html b/console-webapp/src/app/header/header.component.html index 502c2caee..27fb35a49 100644 --- a/console-webapp/src/app/header/header.component.html +++ b/console-webapp/src/app/header/header.component.html @@ -1,6 +1,12 @@

- - - - + +

diff --git a/console-webapp/src/app/header/header.component.scss b/console-webapp/src/app/header/header.component.scss index 3b6f07b19..a0e52456e 100644 --- a/console-webapp/src/app/header/header.component.scss +++ b/console-webapp/src/app/header/header.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,25 +16,27 @@ &__logo { color: inherit; text-decoration: none; + margin-left: -10px; + } + &__menu-btn { + width: 25px; + height: 25px; + padding: 0; } &__header { margin-top: 0; - margin-bottom: 10px; - @media (max-width: 599px) { - .mat-toolbar { - padding: 0; - } - .console-app__logo { - font-size: 16px; - } - button { - padding-left: 0; - padding-right: 0; - width: 30px; - } + margin-bottom: 15px; + + .mat-toolbar { + background: transparent; + margin-bottom: 10px; + } + + @media (max-width: 480px) { + } + + &-user-icon { + margin-left: 20px; } } } -.spacer { - flex: 1; -} diff --git a/console-webapp/src/app/header/header.component.spec.ts b/console-webapp/src/app/header/header.component.spec.ts index 579b7166e..d7e15b5cc 100644 --- a/console-webapp/src/app/header/header.component.spec.ts +++ b/console-webapp/src/app/header/header.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/header/header.component.ts b/console-webapp/src/app/header/header.component.ts index 3be0014c2..edfd1f8d7 100644 --- a/console-webapp/src/app/header/header.component.ts +++ b/console-webapp/src/app/header/header.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ // limitations under the License. import { Component, EventEmitter, Output } from '@angular/core'; +import { BreakPointObserverService } from '../shared/services/breakPoint.service'; @Component({ selector: 'app-header', @@ -22,6 +23,8 @@ import { Component, EventEmitter, Output } from '@angular/core'; export class HeaderComponent { private isNavOpen = false; + constructor(protected breakpointObserver: BreakPointObserverService) {} + @Output() toggleNavOpen = new EventEmitter(); toggleNavPane() { diff --git a/console-webapp/src/app/home/home.component.html b/console-webapp/src/app/home/home.component.html index 0d90720d2..c16a3fb25 100644 --- a/console-webapp/src/app/home/home.component.html +++ b/console-webapp/src/app/home/home.component.html @@ -1,13 +1,52 @@ -
-

Welcome to the Google Registry Console

+
+

Dashboard

-
-
-
-
-
-
-
-
+ + +

+ view_list + DUMs +

+

View Domains

+
+ + + +
+ + + +

+ settings + EPP Passwords +

+

View / Update EPP Password

+
+ + + +
+ + + +

+ account_circle + Registrars +

+

View all registrars

+
+ + + +
diff --git a/console-webapp/src/app/home/home.component.scss b/console-webapp/src/app/home/home.component.scss index f591fdf0f..97ce07942 100644 --- a/console-webapp/src/app/home/home.component.scss +++ b/console-webapp/src/app/home/home.component.scss @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,25 +13,23 @@ // limitations under the License. .console-app { - &__home { - margin-top: 1rem; - } &__home-widgets { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); - grid-gap: 20px; - grid-auto-flow: dense; - + display: flex; + gap: 1rem; + h3 { + padding: 0; + margin: 0; + display: flex; + align-items: center; + gap: 10px; + } mat-card { - height: 100%; - h1 { - margin-top: 1rem; - } + flex: 1; } } - @media (max-width: 510px) { - .console-app__widget-wrapper__wide { - grid-column: initial; + &__home_tablet { + .console-app__home-widgets { + flex-direction: column; } } } diff --git a/console-webapp/src/app/home/home.component.spec.ts b/console-webapp/src/app/home/home.component.spec.ts index 8527db3c8..2201cb4bb 100644 --- a/console-webapp/src/app/home/home.component.spec.ts +++ b/console-webapp/src/app/home/home.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/home/home.component.ts b/console-webapp/src/app/home/home.component.ts index 6ce4e2b53..5b21cc8a0 100644 --- a/console-webapp/src/app/home/home.component.ts +++ b/console-webapp/src/app/home/home.component.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,12 +12,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, ViewEncapsulation } from '@angular/core'; +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { DomainListComponent } from '../domains/domainList.component'; +import { RegistrarComponent } from '../registrar/registrarsTable.component'; +import SecurityComponent from '../settings/security/security.component'; +import { SettingsComponent } from '../settings/settings.component'; +import { BreakPointObserverService } from '../shared/services/breakPoint.service'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'], - encapsulation: ViewEncapsulation.None, }) -export class HomeComponent {} +export class HomeComponent { + constructor( + protected breakPointObserverService: BreakPointObserverService, + private router: Router + ) {} + viewRegistrars() { + this.router.navigate([RegistrarComponent.PATH], { + queryParamsHandling: 'merge', + }); + } + updateEppPassword() { + this.router.navigate( + [SettingsComponent.PATH + '/' + SecurityComponent.PATH], + { queryParamsHandling: 'merge' } + ); + } + viewDums() { + this.router.navigate([DomainListComponent.PATH], { + queryParamsHandling: 'merge', + }); + } +} diff --git a/console-webapp/src/app/home/widgets/billingWidget.component.html b/console-webapp/src/app/home/widgets/billingWidget.component.html deleted file mode 100644 index 5d3352b0d..000000000 --- a/console-webapp/src/app/home/widgets/billingWidget.component.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/console-webapp/src/app/home/widgets/contactWidget.component.html b/console-webapp/src/app/home/widgets/contactWidget.component.html deleted file mode 100644 index a42f21124..000000000 --- a/console-webapp/src/app/home/widgets/contactWidget.component.html +++ /dev/null @@ -1,29 +0,0 @@ - - -
-
- call -

Contact Support

-

- Let us know if you have any questions -

-
-
-
Give us a Call
-

- Call {{ userDataService.userData?.productName }} support at - {{ - userDataService.userData?.supportPhoneNumber - }} -

-
Send us an Email
-

- Email {{ userDataService.userData?.productName }} at - {{ - userDataService.userData?.supportEmail - }} -

-
-
-
-
diff --git a/console-webapp/src/app/home/widgets/contactWidget.component.ts b/console-webapp/src/app/home/widgets/contactWidget.component.ts deleted file mode 100644 index 750221b1e..000000000 --- a/console-webapp/src/app/home/widgets/contactWidget.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { Component } from '@angular/core'; -import { UserDataService } from 'src/app/shared/services/userData.service'; - -@Component({ - selector: '[app-contact-widget]', - templateUrl: './contactWidget.component.html', -}) -export class ContactWidgetComponent { - constructor(public userDataService: UserDataService) {} -} diff --git a/console-webapp/src/app/home/widgets/domainsWidget.component.html b/console-webapp/src/app/home/widgets/domainsWidget.component.html deleted file mode 100644 index f30dcdf9b..000000000 --- a/console-webapp/src/app/home/widgets/domainsWidget.component.html +++ /dev/null @@ -1,30 +0,0 @@ - - -
-
- view_list -

Domains

-

- Manage domain names and registry lock settings. -

-
-
- -

Register a new domain name

- -

- Download a csv of all domains under management -

-
-
-
-
diff --git a/console-webapp/src/app/home/widgets/eppWidget.component.html b/console-webapp/src/app/home/widgets/eppWidget.component.html deleted file mode 100644 index c014b514d..000000000 --- a/console-webapp/src/app/home/widgets/eppWidget.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
-
- computer -

EPP Console

-

- Test run and execute EPP commands using XML files. -

-
-
-
-
diff --git a/console-webapp/src/app/home/widgets/promotionsWidget.component.html b/console-webapp/src/app/home/widgets/promotionsWidget.component.html deleted file mode 100644 index cb0c5b8ba..000000000 --- a/console-webapp/src/app/home/widgets/promotionsWidget.component.html +++ /dev/null @@ -1,27 +0,0 @@ - - -
-
- subject -

Promotions

-

- Manage Google Registry promotions and view onboarding process. -

-
-
- -

- Onboard or view current preferred partner status -

- -

- Onboard or view current registry lock status -

-
-
-
-
diff --git a/console-webapp/src/app/home/widgets/resourcesWidget.component.html b/console-webapp/src/app/home/widgets/resourcesWidget.component.html deleted file mode 100644 index 6caf5335e..000000000 --- a/console-webapp/src/app/home/widgets/resourcesWidget.component.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/console-webapp/src/app/home/widgets/settingsWidget.component.html b/console-webapp/src/app/home/widgets/settingsWidget.component.html deleted file mode 100644 index d75f01104..000000000 --- a/console-webapp/src/app/home/widgets/settingsWidget.component.html +++ /dev/null @@ -1,53 +0,0 @@ - - -
-
- settings -

Settings

-

- Configure registrar settings, manage console users, and view activity - log. -

-
-
- -

Manage Primary, Technical, etc contacts.

- -

- Manage IP allow lists and SSL certificates. -

- -

Reset your Nomulus password.

- -

Create and manage console user accounts

- -

Create and manage registrar accounts

-
-
-
-
diff --git a/console-webapp/src/app/home/widgets/settingsWidget.component.ts b/console-webapp/src/app/home/widgets/settingsWidget.component.ts deleted file mode 100644 index 425cb9757..000000000 --- a/console-webapp/src/app/home/widgets/settingsWidget.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { Component } from '@angular/core'; -import { Router } from '@angular/router'; -import { RegistrarComponent } from 'src/app/registrar/registrarsTable.component'; -import ContactComponent from 'src/app/settings/contact/contact.component'; -import SecurityComponent from 'src/app/settings/security/security.component'; -import { SettingsComponent } from 'src/app/settings/settings.component'; - -@Component({ - selector: '[app-settings-widget]', - templateUrl: './settingsWidget.component.html', -}) -export class SettingsWidgetComponent { - constructor(private router: Router) {} - - openRegistrarsPage() { - this.navigate(RegistrarComponent.PATH); - } - - openSecurityPage() { - this.navigate(SecurityComponent.PATH); - } - - openContactsPage() { - this.navigate(ContactComponent.PATH); - } - - private navigate(route: string) { - this.router.navigate([SettingsComponent.PATH, route]); - } -} diff --git a/console-webapp/src/app/home/widgets/tldsWidget.component.html b/console-webapp/src/app/home/widgets/tldsWidget.component.html deleted file mode 100644 index 99324ed7f..000000000 --- a/console-webapp/src/app/home/widgets/tldsWidget.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
-
- list_alt -

TLDs

-

- View launch phase information for all onboarded and available TLDs. -

-
-
-
-
diff --git a/console-webapp/src/app/material.module.ts b/console-webapp/src/app/material.module.ts index bc5b6b089..cc8fbbf0d 100644 --- a/console-webapp/src/app/material.module.ts +++ b/console-webapp/src/app/material.module.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ import { MatSidenavModule } from '@angular/material/sidenav'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatChipsModule } from '@angular/material/chips'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; @NgModule({ exports: [ @@ -83,6 +84,7 @@ import { MatChipsModule } from '@angular/material/chips'; MatSnackBarModule, MatPaginatorModule, MatChipsModule, + MatAutocompleteModule, ], }) export class MaterialModule {} diff --git a/console-webapp/src/app/navigation/navigation.component.html b/console-webapp/src/app/navigation/navigation.component.html new file mode 100644 index 000000000..745372fdb --- /dev/null +++ b/console-webapp/src/app/navigation/navigation.component.html @@ -0,0 +1,44 @@ + + + + {{ node.iconName }} + + {{ node.title }} + + +
+ + + {{ node.iconName }} + + {{ node.title }} +
+
+ +
+
+
diff --git a/console-webapp/src/app/navigation/navigation.component.scss b/console-webapp/src/app/navigation/navigation.component.scss new file mode 100644 index 000000000..aa73db9b2 --- /dev/null +++ b/console-webapp/src/app/navigation/navigation.component.scss @@ -0,0 +1,71 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +$expand-icon-size: 26px; + +.console-app { + &__sidebar { + min-width: 300px; + border: 0; + } + + &__nav-icon { + width: $expand-icon-size; + height: $expand-icon-size; + color: var(--secondary) !important; + margin-right: $expand-icon-size; + + &_expand { + position: absolute; + left: 0; + margin: auto; + padding: 0px; + width: $expand-icon-size; + height: $expand-icon-size; + } + } + + &__nav-tree { + .mat-tree-node { + cursor: pointer; + padding-left: $expand-icon-size; + position: relative; + + &:hover { + background-color: var(--light-highlight); + border-radius: 0 25px 25px 0; + } + &.active { + border-radius: 0 25px 25px 0; + background-color: var(--lightest); + } + } + + div[role="group"] > .mat-tree-node { + // expand icon + regular icon + spacing = 3 * $expand-icon-size + padding-left: calc($expand-icon-size * 3); + } + + ul, + li { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; + } + + &_invisible { + display: none; + } + } +} diff --git a/console-webapp/src/app/navigation/navigation.component.ts b/console-webapp/src/app/navigation/navigation.component.ts new file mode 100644 index 000000000..55f7938e8 --- /dev/null +++ b/console-webapp/src/app/navigation/navigation.component.ts @@ -0,0 +1,107 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NestedTreeControl } from '@angular/cdk/tree'; +import { Component } from '@angular/core'; +import { MatTreeNestedDataSource } from '@angular/material/tree'; +import { NavigationEnd, Router } from '@angular/router'; +import { Subscription } from 'rxjs'; +import { RouteWithIcon, routes } from '../app-routing.module'; + +interface NavMenuNode extends RouteWithIcon { + parentRoute?: RouteWithIcon; +} + +/** + * This component is responsible for rendering navigation menu based on the allowed routes + * and keeping UI in sync when route changes (eg highlights selected route in the menu). + */ +@Component({ + selector: 'app-navigation', + templateUrl: './navigation.component.html', + styleUrls: ['./navigation.component.scss'], +}) +export class NavigationComponent { + renderRouter: boolean = true; + treeControl = new NestedTreeControl((node) => node.children); + dataSource = new MatTreeNestedDataSource(); + private subscription!: Subscription; + hasChild = (_: number, node: RouteWithIcon) => + !!node.children && node.children.length > 0; + + constructor(protected router: Router) { + this.dataSource.data = this.ngRoutesToNavMenuNodes(routes); + } + + ngOnInit() { + this.subscription = this.router.events.subscribe((navigationParams) => { + if (navigationParams instanceof NavigationEnd) { + this.syncExpandedNavigationWithRoute(navigationParams.url); + } + }); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } + + syncExpandedNavigationWithRoute(url: string) { + const maybeComponentWithChildren = this.dataSource.data.find((menuNode) => { + return ( + // @ts-ignore - optional function added to components with children, + // there's no availble tools to get current active router component + typeof menuNode.component?.matchesUrl === 'function' && + // @ts-ignore + menuNode.component?.matchesUrl(url) + ); + }); + if (maybeComponentWithChildren) { + this.treeControl.expand(maybeComponentWithChildren); + } + } + + onClick(node: NavMenuNode) { + if (node.parentRoute) { + this.router.navigate([node.parentRoute.path + '/' + node.path], { + queryParamsHandling: 'merge', + }); + } else { + this.router.navigate([node.path], { queryParamsHandling: 'merge' }); + } + } + + /** + * We only want to use routes with titles and we want to provide easy reference to parent node + */ + ngRoutesToNavMenuNodes(routes: RouteWithIcon[]): NavMenuNode[] { + return routes + .filter((r) => r.title) + .map((r) => { + if (r.children) { + return { + ...r, + children: r.children + .filter((r) => r.title) + .map((childRoute) => { + return { + ...childRoute, + parentRoute: r, + }; + }), + }; + } + return r; + }); + } +} diff --git a/console-webapp/src/app/registrar/emptyRegistrar.component.html b/console-webapp/src/app/registrar/emptyRegistrar.component.html deleted file mode 100644 index e77cdc8b3..000000000 --- a/console-webapp/src/app/registrar/emptyRegistrar.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
-

- block -

-

No registrar selected

-

Please select a registrar

-
diff --git a/console-webapp/src/app/registrar/emptyRegistrar.component.ts b/console-webapp/src/app/registrar/emptyRegistrar.component.ts deleted file mode 100644 index 02521b104..000000000 --- a/console-webapp/src/app/registrar/emptyRegistrar.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { Component, effect } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; - -import { RegistrarService } from './registrar.service'; - -@Component({ - selector: 'app-empty-registrar', - templateUrl: './emptyRegistrar.component.html', - styleUrls: ['./emptyRegistrar.component.scss'], -}) -export class EmptyRegistrar { - constructor( - private route: ActivatedRoute, - protected registrarService: RegistrarService, - private router: Router - ) { - effect(() => { - if (registrarService.registrarId()) { - this.router.navigate([this.route.snapshot.paramMap.get('nextUrl')]); - } - }); - } -} diff --git a/console-webapp/src/app/registrar/registrar.guard.spec.ts b/console-webapp/src/app/registrar/registrar.guard.spec.ts deleted file mode 100644 index ec4618c6b..000000000 --- a/console-webapp/src/app/registrar/registrar.guard.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { TestBed } from '@angular/core/testing'; - -import { RegistrarGuard } from './registrar.guard'; -import { - ActivatedRouteSnapshot, - Router, - RouterStateSnapshot, -} from '@angular/router'; -import { RegistrarService } from './registrar.service'; - -describe('RegistrarGuard', () => { - let guard: RegistrarGuard; - let dummyRegistrarService: RegistrarService; - let routeSpy: Router; - let dummyRoute: RouterStateSnapshot; - - beforeEach(() => { - routeSpy = jasmine.createSpyObj('Router', ['navigate']); - dummyRegistrarService = { activeRegistrarId: '' } as RegistrarService; - dummyRoute = { url: '/value' } as RouterStateSnapshot; - - TestBed.configureTestingModule({ - providers: [ - RegistrarGuard, - { provide: Router, useValue: routeSpy }, - { provide: RegistrarService, useValue: dummyRegistrarService }, - ], - }); - }); - - it('should not be able to activate when activeRegistrarId is empty', () => { - guard = TestBed.inject(RegistrarGuard); - const res = guard.canActivate(new ActivatedRouteSnapshot(), dummyRoute); - expect(res).toBeFalsy(); - }); - - it('should be able to activate when activeRegistrarId is not empty', () => { - TestBed.overrideProvider(RegistrarService, { - useValue: { activeRegistrarId: 'value' }, - }); - guard = TestBed.inject(RegistrarGuard); - const res = guard.canActivate(new ActivatedRouteSnapshot(), dummyRoute); - expect(res).toBeTrue(); - }); - - it('should navigate to empty-registrar screen when activeRegistrarId is empty', () => { - guard = TestBed.inject(RegistrarGuard); - guard.canActivate(new ActivatedRouteSnapshot(), dummyRoute); - expect(routeSpy.navigate).toHaveBeenCalledOnceWith([ - '/empty-registrar', - { nextUrl: dummyRoute.url }, - ]); - }); -}); diff --git a/console-webapp/src/app/registrar/registrar.guard.ts b/console-webapp/src/app/registrar/registrar.guard.ts deleted file mode 100644 index c79b59aa8..000000000 --- a/console-webapp/src/app/registrar/registrar.guard.ts +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { Injectable } from '@angular/core'; -import { - ActivatedRouteSnapshot, - Router, - RouterStateSnapshot, -} from '@angular/router'; - -import { RegistrarService } from './registrar.service'; - -@Injectable({ - providedIn: 'root', -}) -export class RegistrarGuard { - constructor( - private router: Router, - private registrarService: RegistrarService - ) {} - - canActivate( - _: ActivatedRouteSnapshot, - state: RouterStateSnapshot - ): Promise | boolean { - if (this.registrarService.registrarId()) { - return true; - } - return this.router.navigate([ - `/empty-registrar`, - { nextUrl: state.url || '' }, - ]); - } -} diff --git a/console-webapp/src/app/registrar/registrar.service.spec.ts b/console-webapp/src/app/registrar/registrar.service.spec.ts index 49f140899..85c1ed95f 100644 --- a/console-webapp/src/app/registrar/registrar.service.spec.ts +++ b/console-webapp/src/app/registrar/registrar.service.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/registrar/registrar.service.ts b/console-webapp/src/app/registrar/registrar.service.ts index 8beb662b5..51ec29df5 100644 --- a/console-webapp/src/app/registrar/registrar.service.ts +++ b/console-webapp/src/app/registrar/registrar.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,44 +15,53 @@ import { Injectable, computed, signal } from '@angular/core'; import { Observable, tap } from 'rxjs'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { Router } from '@angular/router'; import { BackendService } from '../shared/services/backend.service'; import { GlobalLoader, GlobalLoaderService, } from '../shared/services/globalLoader.service'; -import { MatSnackBar } from '@angular/material/snack-bar'; export interface Address { - street?: string[]; city?: string; countryCode?: string; - zip?: string; state?: string; + street?: string[]; + zip?: string; } -export interface Registrar { +export interface WhoisRegistrarFields { + ianaIdentifier?: number; + icannReferralEmail: string; + localizedAddress: Address; + registrarId: string; + url: string; + whoisServer: string; +} + +export interface Registrar extends WhoisRegistrarFields { allowedTlds?: string[]; billingAccountMap?: object; driveFolderId?: string; emailAddress?: string; faxNumber?: string; - ianaIdentifier?: number; - icannReferralEmail?: string; ipAddressAllowList?: string[]; - localizedAddress?: Address; phoneNumber?: string; registrarId: string; registrarName: string; registryLockAllowed?: boolean; - url?: string; - whoisServer?: string; } @Injectable({ providedIn: 'root', }) export class RegistrarService implements GlobalLoader { - registrarId = signal(''); + registrarId = signal( + new URLSearchParams(document.location.hash.split('?')[1]).get( + 'registrarId' + ) || '' + ); registrars = signal([]); registrar = computed(() => this.registrars().find((r) => r.registrarId === this.registrarId()) @@ -61,7 +70,8 @@ export class RegistrarService implements GlobalLoader { constructor( private backend: BackendService, private globalLoader: GlobalLoaderService, - private _snackBar: MatSnackBar + private _snackBar: MatSnackBar, + private router: Router ) { this.loadRegistrars().subscribe((r) => { this.globalLoader.stopGlobalLoader(this); @@ -70,7 +80,14 @@ export class RegistrarService implements GlobalLoader { } public updateSelectedRegistrar(registrarId: string) { - this.registrarId.set(registrarId); + if (registrarId !== this.registrarId()) { + this.registrarId.set(registrarId); + // add registrarId to url query params, so that we can pick it up after page refresh + this.router.navigate([], { + queryParams: { registrarId }, + queryParamsHandling: 'merge', + }); + } } public loadRegistrars(): Observable { @@ -83,6 +100,23 @@ export class RegistrarService implements GlobalLoader { ); } + saveRegistrar(registrar: Registrar) { + return this.backend.postRegistrar(registrar).pipe( + tap((registrar) => { + if (registrar) { + this.registrars.set( + this.registrars().map((r) => { + if (r.registrarId === registrar.registrarId) { + return registrar; + } + return r; + }) + ); + } + }) + ); + } + loadingTimeout() { this._snackBar.open('Timeout loading registrars'); } diff --git a/console-webapp/src/app/registrar/registrarDetails.component.html b/console-webapp/src/app/registrar/registrarDetails.component.html index c1c9a4df7..de6c78f47 100644 --- a/console-webapp/src/app/registrar/registrarDetails.component.html +++ b/console-webapp/src/app/registrar/registrarDetails.component.html @@ -1,40 +1,99 @@ -
-

Edit Registrar: {{ registrarInEdit.registrarId }}

-
+
+

Registrars

+ +
+
+ +
+ @if(!inEdit && !registrarNotFound) { + + + } +
+ @if(registrarNotFound) { +

Registrar not found

+ } @else { +

{{ registrarInEdit.registrarId }}

+

+ {{ registrarInEdit.registrarName }} +

+ @if(inEdit) {
- - Registry Lock: - - True - False - - - - Onboarded TLDs: - - + + Registry Lock: + - {{ tld }} - - - - - - - - - + True + False + + +
+
+ + Onboarded TLDs: + + + {{ tld }} + + + + + +
+ + } @else { + + + + +

Registrar details

+
+ + @for (column of columns; track column.columnDef) { + + {{ column.header }} + + + + } +
+
+
+ } }
diff --git a/console-webapp/src/app/registrar/registrarDetails.component.scss b/console-webapp/src/app/registrar/registrarDetails.component.scss index 132f0d566..4e4c59a18 100644 --- a/console-webapp/src/app/registrar/registrarDetails.component.scss +++ b/console-webapp/src/app/registrar/registrarDetails.component.scss @@ -1,8 +1,19 @@ -.registrarDetails { - min-width: 30vw; - - &__input { - display: block; - margin-top: 0.5rem; +.console-app { + &__registrar-view { + &-controls { + display: flex; + align-items: center; + margin: 20px 0; + } + } + &__registrar-view-content { + max-width: 616px; + mat-divider:last-child { + display: none; + } + mat-form-field { + margin-bottom: 20px; + width: 100%; + } } } diff --git a/console-webapp/src/app/registrar/registrarDetails.component.ts b/console-webapp/src/app/registrar/registrarDetails.component.ts index 47b0aaf2b..d306b31bd 100644 --- a/console-webapp/src/app/registrar/registrarDetails.component.ts +++ b/console-webapp/src/app/registrar/registrarDetails.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,38 +12,51 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component } from '@angular/core'; -import { Registrar, RegistrarService } from './registrar.service'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnInit } from '@angular/core'; import { MatChipInputEvent } from '@angular/material/chips'; -import { DialogBottomSheetContent } from '../shared/components/dialogBottomSheet.component'; - -type RegistrarDetailsParams = { - close: Function; - data: { - registrar: Registrar; - }; -}; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { Subscription } from 'rxjs'; +import { Registrar, RegistrarService } from './registrar.service'; +import { RegistrarComponent, columns } from './registrarsTable.component'; @Component({ selector: 'app-registrar-details', templateUrl: './registrarDetails.component.html', styleUrls: ['./registrarDetails.component.scss'], }) -export class RegistrarDetailsComponent implements DialogBottomSheetContent { +export class RegistrarDetailsComponent implements OnInit { + public static PATH = 'registrars/:id'; + inEdit: boolean = false; registrarInEdit!: Registrar; - params?: RegistrarDetailsParams; + registrarNotFound: boolean = false; + columns = columns.filter((c) => !c.hiddenOnDetailsCard); + private subscription!: Subscription; - constructor(protected registrarService: RegistrarService) {} + constructor( + protected registrarService: RegistrarService, + private route: ActivatedRoute, + private _snackBar: MatSnackBar, + private router: Router + ) {} - init(params: RegistrarDetailsParams) { - this.params = params; - this.registrarInEdit = JSON.parse( - JSON.stringify(this.params.data.registrar) - ); - } - - saveAndClose() { - this.params?.close(); + ngOnInit(): void { + this.subscription = this.route.paramMap.subscribe((params: ParamMap) => { + this.registrarInEdit = structuredClone( + this.registrarService + .registrars() + .filter((r) => r.registrarId === params.get('id'))[0] + ); + if (!this.registrarInEdit) { + this._snackBar.open( + `Registrar with id ${params.get('id')} is not available` + ); + this.registrarNotFound = true; + } else { + this.registrarNotFound = false; + } + }); } addTLD(e: MatChipInputEvent) { @@ -58,4 +71,22 @@ export class RegistrarDetailsComponent implements DialogBottomSheetContent { (v) => v != tld ); } + + saveAndClose() { + this.registrarService.saveRegistrar(this.registrarInEdit).subscribe({ + complete: () => { + this.router.navigate([RegistrarComponent.PATH], { + queryParamsHandling: 'merge', + }); + }, + error: (err: HttpErrorResponse) => { + this._snackBar.open(err.error); + }, + }); + this.inEdit = false; + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } } diff --git a/console-webapp/src/app/registrar/registrarSelector.component.html b/console-webapp/src/app/registrar/registrarSelector.component.html index 4b8cf5250..6d05f3094 100644 --- a/console-webapp/src/app/registrar/registrarSelector.component.html +++ b/console-webapp/src/app/registrar/registrarSelector.component.html @@ -1,29 +1,32 @@
- - - - Registrar - Registrar + + + @for (registrarId of filteredOptions; track registrarId) { + {{ registrarId }} - - {{ registrar.registrarId }} - - - - + } + +
diff --git a/console-webapp/src/app/registrar/registrarSelector.component.scss b/console-webapp/src/app/registrar/registrarSelector.component.scss index ca1ba08f4..fc2cf2a6b 100644 --- a/console-webapp/src/app/registrar/registrarSelector.component.scss +++ b/console-webapp/src/app/registrar/registrarSelector.component.scss @@ -3,16 +3,5 @@ display: flex; justify-content: center; align-items: baseline; - // Fix for angular v15 label issue - // https://github.com/angular/components/issues/26579 - .mat-mdc-floating-label { - display: inline !important; - } - .mat-mdc-select-arrow-wrapper { - transform: translateY(0) !important; - } - } - &__title { - margin-right: 1rem; } } diff --git a/console-webapp/src/app/registrar/registrarSelector.component.spec.ts b/console-webapp/src/app/registrar/registrarSelector.component.spec.ts index 0080b3142..297e88ac1 100644 --- a/console-webapp/src/app/registrar/registrarSelector.component.spec.ts +++ b/console-webapp/src/app/registrar/registrarSelector.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/registrar/registrarSelector.component.ts b/console-webapp/src/app/registrar/registrarSelector.component.ts index ea6d942a9..22f4ec358 100644 --- a/console-webapp/src/app/registrar/registrarSelector.component.ts +++ b/console-webapp/src/app/registrar/registrarSelector.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,35 +12,37 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, OnInit } from '@angular/core'; +import { Component, computed, effect, signal } from '@angular/core'; import { RegistrarService } from './registrar.service'; -import { BreakpointObserver } from '@angular/cdk/layout'; -import { distinctUntilChanged } from 'rxjs'; - -const MOBILE_LAYOUT_BREAKPOINT = '(max-width: 599px)'; @Component({ selector: 'app-registrar-selector', templateUrl: './registrarSelector.component.html', styleUrls: ['./registrarSelector.component.scss'], }) -export class RegistrarSelectorComponent implements OnInit { - protected isMobile: boolean = false; +export class RegistrarSelectorComponent { + registrarInput = signal(this.registrarService.registrarId()); + filteredOptions?: string[]; + allRegistrarIds = computed(() => + this.registrarService.registrars().map((r) => r.registrarId) + ); - readonly breakpoint$ = this.breakpointObserver - .observe([MOBILE_LAYOUT_BREAKPOINT]) - .pipe(distinctUntilChanged()); - - constructor( - protected registrarService: RegistrarService, - protected breakpointObserver: BreakpointObserver - ) {} - - ngOnInit(): void { - this.breakpoint$.subscribe(() => this.breakpointChanged()); + constructor(protected registrarService: RegistrarService) { + effect(() => { + const filterValue = this.registrarInput().toLowerCase(); + this.filteredOptions = this.allRegistrarIds().filter((option) => + option.toLowerCase().includes(filterValue) + ); + }); + this.onSelect(registrarService.registrarId()); } - private breakpointChanged() { - this.isMobile = this.breakpointObserver.isMatched(MOBILE_LAYOUT_BREAKPOINT); + onSelect(registrarId: string) { + this.registrarService.updateSelectedRegistrar(registrarId); + + // We reset the list of options after selection, so that user doesn't have to clear it out + setTimeout(() => { + this.filteredOptions = this.allRegistrarIds(); + }, 10); } } diff --git a/console-webapp/src/app/registrar/registrarsTable.component.html b/console-webapp/src/app/registrar/registrarsTable.component.html index 26feb6cd3..8922f06f5 100644 --- a/console-webapp/src/app/registrar/registrarsTable.component.html +++ b/console-webapp/src/app/registrar/registrarsTable.component.html @@ -1,4 +1,5 @@
+

Registrars

Search - - - - - - - -
diff --git a/console-webapp/src/app/registrar/registrarsTable.component.scss b/console-webapp/src/app/registrar/registrarsTable.component.scss index 21db917ae..e8ab32ce1 100644 --- a/console-webapp/src/app/registrar/registrarsTable.component.scss +++ b/console-webapp/src/app/registrar/registrarsTable.component.scss @@ -2,7 +2,6 @@ $min-width: 756px; &__registrars { - margin-top: 1.5rem; width: 100%; overflow: auto; } diff --git a/console-webapp/src/app/registrar/registrarsTable.component.spec.ts b/console-webapp/src/app/registrar/registrarsTable.component.spec.ts index 2ee085cba..5c1fcc684 100644 --- a/console-webapp/src/app/registrar/registrarsTable.component.spec.ts +++ b/console-webapp/src/app/registrar/registrarsTable.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/registrar/registrarsTable.component.ts b/console-webapp/src/app/registrar/registrarsTable.component.ts index 9dfb2c38a..ffa31b492 100644 --- a/console-webapp/src/app/registrar/registrarsTable.component.ts +++ b/console-webapp/src/app/registrar/registrarsTable.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,12 +13,60 @@ // limitations under the License. import { Component, ViewChild, ViewEncapsulation } from '@angular/core'; -import { Registrar, RegistrarService } from './registrar.service'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; -import { RegistrarDetailsComponent } from './registrarDetails.component'; -import { DialogBottomSheetWrapper } from '../shared/components/dialogBottomSheet.component'; +import { Router } from '@angular/router'; +import { Registrar, RegistrarService } from './registrar.service'; + +export const columns = [ + { + columnDef: 'registrarId', + header: 'Registrar Id', + cell: (record: Registrar) => `${record.registrarId || ''}`, + hiddenOnDetailsCard: true, + }, + { + columnDef: 'registrarName', + header: 'Name', + cell: (record: Registrar) => `${record.registrarName || ''}`, + hiddenOnDetailsCard: true, + }, + { + columnDef: 'allowedTlds', + header: 'TLDs', + cell: (record: Registrar) => `${(record.allowedTlds || []).join(', ')}`, + }, + { + columnDef: 'emailAddress', + header: 'Username', + cell: (record: Registrar) => `${record.emailAddress || ''}`, + }, + { + columnDef: 'ianaIdentifier', + header: 'IANA ID', + cell: (record: Registrar) => `${record.ianaIdentifier || ''}`, + }, + { + columnDef: 'billingAccountMap', + header: 'Billing Accounts', + cell: (record: Registrar) => + // @ts-ignore - completely legit line, but TS keeps complaining + `${Object.entries(record.billingAccountMap).reduce((acc, [key, val]) => { + return `${acc}${key}=${val}
`; + }, '')}`, + }, + { + columnDef: 'registryLockAllowed', + header: 'Registry Lock', + cell: (record: Registrar) => `${record.registryLockAllowed}`, + }, + { + columnDef: 'driveId', + header: 'Drive ID', + cell: (record: Registrar) => `${record.driveFolderId || ''}`, + }, +]; @Component({ selector: 'app-registrar', @@ -29,63 +77,17 @@ import { DialogBottomSheetWrapper } from '../shared/components/dialogBottomSheet export class RegistrarComponent { public static PATH = 'registrars'; dataSource: MatTableDataSource; - columns = [ - { - columnDef: 'registrarId', - header: 'Registrar Id', - cell: (record: Registrar) => `${record.registrarId || ''}`, - }, - { - columnDef: 'registrarName', - header: 'Name', - cell: (record: Registrar) => `${record.registrarName || ''}`, - }, - { - columnDef: 'allowedTlds', - header: 'TLDs', - cell: (record: Registrar) => `${(record.allowedTlds || []).join(', ')}`, - }, - { - columnDef: 'emailAddress', - header: 'Username', - cell: (record: Registrar) => `${record.emailAddress || ''}`, - }, - { - columnDef: 'ianaIdentifier', - header: 'IANA ID', - cell: (record: Registrar) => `${record.ianaIdentifier || ''}`, - }, - { - columnDef: 'billingAccountMap', - header: 'Billing Accounts', - cell: (record: Registrar) => - // @ts-ignore - completely legit line, but TS keeps complaining - `${Object.entries(record.billingAccountMap).reduce( - (acc, [key, val]) => { - return `${acc}${key}=${val}
`; - }, - '' - )}`, - }, - { - columnDef: 'registryLockAllowed', - header: 'Registry Lock', - cell: (record: Registrar) => `${record.registryLockAllowed}`, - }, - { - columnDef: 'driveId', - header: 'Drive ID', - cell: (record: Registrar) => `${record.driveFolderId || ''}`, - }, - ]; - displayedColumns = ['edit'].concat(this.columns.map((c) => c.columnDef)); + columns = columns; + + displayedColumns = this.columns.map((c) => c.columnDef); @ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatSort) sort!: MatSort; - @ViewChild('registrarDetailsView') - detailsComponentWrapper!: DialogBottomSheetWrapper; - constructor(protected registrarService: RegistrarService) { + constructor( + protected registrarService: RegistrarService, + private router: Router + ) { this.dataSource = new MatTableDataSource( registrarService.registrars() ); @@ -96,16 +98,15 @@ export class RegistrarComponent { this.dataSource.sort = this.sort; } - openDetails(event: MouseEvent, registrar: Registrar) { - event.stopPropagation(); - this.detailsComponentWrapper.open( - RegistrarDetailsComponent, - { registrar } - ); + openDetails(registrarId: string) { + this.router.navigate(['registrars/', registrarId], { + queryParamsHandling: 'merge', + }); } applyFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value; + // TODO: consider filteing out only by registrar name this.dataSource.filter = filterValue.trim().toLowerCase(); } } diff --git a/console-webapp/src/app/resources/resources.component.html b/console-webapp/src/app/resources/resources.component.html new file mode 100644 index 000000000..1ed9ccbbb --- /dev/null +++ b/console-webapp/src/app/resources/resources.component.html @@ -0,0 +1,15 @@ +

Resource

+
+
+
Technical resources
+ View on Google Drive +
+
+ +
+
diff --git a/console-webapp/src/app/resources/resources.component.scss b/console-webapp/src/app/resources/resources.component.scss new file mode 100644 index 000000000..1e0ae4c17 --- /dev/null +++ b/console-webapp/src/app/resources/resources.component.scss @@ -0,0 +1,22 @@ +.console-app__resources { + display: flex; + flex-wrap: wrap-reverse; + > div { + flex: 1; + display: flex; + justify-content: center; + flex-direction: column; + text-align: left; + max-width: 300px; + min-width: 200px; + margin-top: 30px; + } + img { + aspect-ratio: 1 / 1; + width: 100%; + } + &-subhead { + font-size: 20px; + margin-bottom: 20px; + } +} diff --git a/console-webapp/src/app/home/widgets/resourcesWidget.component.ts b/console-webapp/src/app/resources/resources.component.ts similarity index 61% rename from console-webapp/src/app/home/widgets/resourcesWidget.component.ts rename to console-webapp/src/app/resources/resources.component.ts index 7aad3d3e7..f9d62e1ad 100644 --- a/console-webapp/src/app/home/widgets/resourcesWidget.component.ts +++ b/console-webapp/src/app/resources/resources.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,12 +13,14 @@ // limitations under the License. import { Component } from '@angular/core'; -import { UserDataService } from 'src/app/shared/services/userData.service'; +import { UserDataService } from '../shared/services/userData.service'; @Component({ - selector: '[app-resources-widget]', - templateUrl: './resourcesWidget.component.html', + selector: 'app-resources', + templateUrl: './resources.component.html', + styleUrls: ['./resources.component.scss'], }) -export class ResourcesWidgetComponent { - constructor(public userDataService: UserDataService) {} +export class ResourcesComponent { + public static PATH = 'resources'; + constructor(protected userDataService: UserDataService) {} } diff --git a/console-webapp/src/app/settings/contact/contact.component.html b/console-webapp/src/app/settings/contact/contact.component.html index a034e69b6..118018472 100644 --- a/console-webapp/src/app/settings/contact/contact.component.html +++ b/console-webapp/src/app/settings/contact/contact.component.html @@ -1,48 +1,40 @@ -@if (loading) { -
- -
+@if(contactService.isContactDetailsView || contactService.isContactNewView) { + } @else { -
+
+ +
+
@if (contactService.contacts().length === 0) { -
- + apps_outage

No contacts found

- } @else { @for (group of groupedContacts(); track group.emailAddress) { -
-

{{ group.label }}s

- -
- - {{ contact.name }} -

{{ contact.phoneNumber }}

-

{{ contact.emailAddress }}

- - - - -
-
-
- } } -
- -
- + } @else { + + + {{ column.header }} + + + + + + }
} diff --git a/console-webapp/src/app/settings/contact/contact.component.scss b/console-webapp/src/app/settings/contact/contact.component.scss index 5a962213c..d4a8c5e59 100644 --- a/console-webapp/src/app/settings/contact/contact.component.scss +++ b/console-webapp/src/app/settings/contact/contact.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,30 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -.contact { - &__cards-wrapper { - margin-top: 22px; - } - &__card { - width: 400px; - padding: 15px; - } - &__card-actions { - padding: 0; - } - &__loading { - margin: 2rem 0; - } - &__cards { - display: flex; - flex-wrap: wrap; - gap: 20px; - margin-top: 20px; - } - &__actions { - display: flex; - justify-content: flex-start; - margin: 2rem 0; +.console-app { + &__contacts { + margin-top: -10px; + width: 100%; + overflow: auto; + mat-table { + min-width: 800px; + } } &__empty-contacts { display: flex; @@ -49,22 +33,14 @@ font-size: 4rem; margin-top: 1.5rem; } -} -.contact-details { - &__input { - width: 100%; + &__contacts-controls { + position: absolute; + right: 20px; + top: 5px; } - &__group { - margin: 20px 0; - display: flex; - align-items: baseline; - } - &__group-content { - display: flex; - flex-wrap: wrap; - max-width: 450px; - * { - min-width: 200px; - } + .contact__name-column-title { + color: #5f6368; + font-weight: 500; + padding: 10px 0; } } diff --git a/console-webapp/src/app/settings/contact/contact.component.spec.ts b/console-webapp/src/app/settings/contact/contact.component.spec.ts index 26726ef51..70a2be2d2 100644 --- a/console-webapp/src/app/settings/contact/contact.component.spec.ts +++ b/console-webapp/src/app/settings/contact/contact.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/contact/contact.component.ts b/console-webapp/src/app/settings/contact/contact.component.ts index b5e7bef2f..ba51f6f13 100644 --- a/console-webapp/src/app/settings/contact/contact.component.ts +++ b/console-webapp/src/app/settings/contact/contact.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,101 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, ViewChild, computed } from '@angular/core'; -import { Contact, ContactService } from './contact.service'; -import { HttpErrorResponse } from '@angular/common/http'; -import { MatSnackBar } from '@angular/material/snack-bar'; +import { Component, effect } from '@angular/core'; +import { MatTableDataSource } from '@angular/material/table'; +import { take } from 'rxjs'; +import { RegistrarService } from 'src/app/registrar/registrar.service'; import { - DialogBottomSheetContent, - DialogBottomSheetWrapper, -} from 'src/app/shared/components/dialogBottomSheet.component'; - -enum Operations { - DELETE, - ADD, - UPDATE, -} - -interface GroupedContacts { - value: string; - label: string; - contacts: Array; -} - -type ContactDetailsParams = { - close: Function; - data: { - contact: Contact; - operation: Operations; - }; -}; - -const contactTypes: Array = [ - { value: 'ADMIN', label: 'Primary contact', contacts: [] }, - { value: 'ABUSE', label: 'Abuse contact', contacts: [] }, - { value: 'BILLING', label: 'Billing contact', contacts: [] }, - { value: 'LEGAL', label: 'Legal contact', contacts: [] }, - { value: 'MARKETING', label: 'Marketing contact', contacts: [] }, - { value: 'TECH', label: 'Technical contact', contacts: [] }, - { value: 'WHOIS', label: 'WHOIS-Inquiry contact', contacts: [] }, -]; - -@Component({ - selector: 'app-contact-details-dialog', - templateUrl: 'contactDetails.component.html', - styleUrls: ['./contact.component.scss'], -}) -export class ContactDetailsDialogComponent implements DialogBottomSheetContent { - contact?: Contact; - contactTypes = contactTypes; - contactIndex?: number; - - params?: ContactDetailsParams; - - constructor( - public contactService: ContactService, - private _snackBar: MatSnackBar - ) {} - - init(params: ContactDetailsParams) { - this.params = params; - this.contactIndex = this.contactService - .contacts() - .findIndex((c) => c === params.data.contact); - this.contact = JSON.parse(JSON.stringify(params.data.contact)); - } - - close() { - this.params?.close(); - } - - saveAndClose(e: SubmitEvent) { - e.preventDefault(); - if (!this.contact || this.contactIndex === undefined) return; - if (!(e.target as HTMLFormElement).checkValidity()) { - return; - } - const operation = this.params?.data.operation; - let operationObservable; - if (operation === Operations.ADD) { - operationObservable = this.contactService.addContact(this.contact); - } else if (operation === Operations.UPDATE) { - operationObservable = this.contactService.updateContact( - this.contactIndex, - this.contact - ); - } else { - throw 'Unknown operation type'; - } - - operationObservable.subscribe({ - complete: () => this.close(), - error: (err: HttpErrorResponse) => { - this._snackBar.open(err.error); - }, - }); - } -} + Contact, + ContactService, + ViewReadyContact, + contactTypeToViewReadyContact, +} from './contact.service'; @Component({ selector: 'app-contact', @@ -115,61 +30,67 @@ export class ContactDetailsDialogComponent implements DialogBottomSheetContent { }) export default class ContactComponent { public static PATH = 'contact'; - public groupedContacts = computed(() => { - return this.contactService.contacts().reduce((acc, contact) => { - contact.types.forEach((contactType) => { - acc - .find((group: GroupedContacts) => group.value === contactType) - ?.contacts.push(contact); - }); - return acc; - }, JSON.parse(JSON.stringify(contactTypes))); - }); - @ViewChild('contactDetailsWrapper') - detailsComponentWrapper!: DialogBottomSheetWrapper; + dataSource: MatTableDataSource = + new MatTableDataSource([]); + columns = [ + { + columnDef: 'name', + header: 'Name', + cell: (contact: ViewReadyContact) => ` +
+
${contact.name}
+
${contact.userFriendlyTypes.join( + ' • ' + )}
+
+ `, + }, + { + columnDef: 'emailAddress', + header: 'Email', + cell: (contact: ViewReadyContact) => `${contact.emailAddress || ''}`, + }, + { + columnDef: 'phoneNumber', + header: 'Phone', + cell: (contact: ViewReadyContact) => `${contact.phoneNumber || ''}`, + }, + { + columnDef: 'faxNumber', + header: 'Fax', + cell: (contact: ViewReadyContact) => `${contact.faxNumber || ''}`, + }, + ]; + displayedColumns = this.columns.map((c) => c.columnDef); - loading: boolean = false; constructor( public contactService: ContactService, - private _snackBar: MatSnackBar + private registrarService: RegistrarService ) { - // TODO: Refactor to registrarId service - this.loading = true; - this.contactService.fetchContacts().subscribe(() => { - this.loading = false; + effect(() => { + if (this.registrarService.registrarId()) { + this.contactService.isContactDetailsView = false; + this.contactService.isContactNewView = false; + this.contactService + .fetchContacts() + .pipe(take(1)) + .subscribe((contacts) => { + this.dataSource = new MatTableDataSource( + contacts.map(contactTypeToViewReadyContact) + ); + }); + } }); } - deleteContact(contact: Contact) { - if (confirm(`Please confirm contact ${contact.name} delete`)) { - this.contactService.deleteContact(contact).subscribe({ - error: (err: HttpErrorResponse) => { - this._snackBar.open(err.error); - }, - }); - } + openDetails(contact: Contact) { + this.contactService.setEditableContact(contact); + this.contactService.isContactDetailsView = true; } - openCreateNew(e: MouseEvent) { - const newContact: Contact = { - name: '', - phoneNumber: '', - emailAddress: '', - types: [contactTypes[0].value], - }; - this.openDetails(e, newContact, Operations.ADD); - } - - openDetails( - e: MouseEvent, - contact: Contact, - operation: Operations = Operations.UPDATE - ) { - e.preventDefault(); - this.detailsComponentWrapper.open( - ContactDetailsDialogComponent, - { contact, operation } - ); + openNewContact() { + this.contactService.setEditableContact(); + this.contactService.isContactNewView = true; } } diff --git a/console-webapp/src/app/settings/contact/contact.service.ts b/console-webapp/src/app/settings/contact/contact.service.ts index 617e2fab6..01a10273a 100644 --- a/console-webapp/src/app/settings/contact/contact.service.ts +++ b/console-webapp/src/app/settings/contact/contact.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,65 +13,112 @@ // limitations under the License. import { Injectable, signal } from '@angular/core'; -import { Observable, tap } from 'rxjs'; +import { Observable, switchMap, tap } from 'rxjs'; import { RegistrarService } from 'src/app/registrar/registrar.service'; import { BackendService } from 'src/app/shared/services/backend.service'; +export type contactType = + | 'ADMIN' + | 'ABUSE' + | 'BILLING' + | 'LEGAL' + | 'MARKETING' + | 'TECH' + | 'WHOIS'; + +type contactTypesToUserFriendlyTypes = { [type in contactType]: string }; + +export const contactTypeToTextMap: contactTypesToUserFriendlyTypes = { + ADMIN: 'Primary contact', + ABUSE: 'Abuse contact', + BILLING: 'Billing contact', + LEGAL: 'Legal contact', + MARKETING: 'Marketing contact', + TECH: 'Technical contact', + WHOIS: 'WHOIS-Inquiry contact', +}; + +type UserFriendlyType = (typeof contactTypeToTextMap)[contactType]; + export interface Contact { name: string; - phoneNumber: string; + phoneNumber?: string; emailAddress: string; registrarId?: string; faxNumber?: string; - types: Array; + types: Array; visibleInWhoisAsAdmin?: boolean; visibleInWhoisAsTech?: boolean; visibleInDomainWhoisAsAbuse?: boolean; } +export interface ViewReadyContact extends Contact { + userFriendlyTypes: Array; +} + +export function contactTypeToViewReadyContact(c: Contact): ViewReadyContact { + return { + ...c, + userFriendlyTypes: c.types?.map((cType) => contactTypeToTextMap[cType]), + }; +} + @Injectable({ providedIn: 'root', }) export class ContactService { - contacts = signal([]); + contacts = signal([]); + contactInEdit!: ViewReadyContact; + isContactDetailsView: boolean = false; + isContactNewView: boolean = false; constructor( private backend: BackendService, private registrarService: RegistrarService ) {} - // TODO: Come up with a better handling for registrarId + setEditableContact(contact?: Contact) { + this.contactInEdit = contactTypeToViewReadyContact( + contact + ? contact + : { + emailAddress: '', + name: '', + types: ['ADMIN'], + faxNumber: '', + phoneNumber: '', + registrarId: '', + } + ); + } + fetchContacts(): Observable { return this.backend.getContacts(this.registrarService.registrarId()).pipe( - tap((contacts = []) => { - this.contacts.set(contacts); + tap((contacts) => { + this.contacts.set(contacts.map(contactTypeToViewReadyContact)); }) ); } - saveContacts(contacts: Contact[]): Observable { + saveContacts(contacts: ViewReadyContact[]): Observable { return this.backend .postContacts(this.registrarService.registrarId(), contacts) - .pipe( - tap((_) => { - this.contacts.set(contacts); - }) - ); + .pipe(switchMap((_) => this.fetchContacts())); } - updateContact(index: number, contact: Contact) { + updateContact(index: number, contact: ViewReadyContact) { const newContacts = this.contacts().map((c, i) => i === index ? contact : c ); return this.saveContacts(newContacts); } - addContact(contact: Contact) { + addContact(contact: ViewReadyContact) { const newContacts = this.contacts().concat([contact]); return this.saveContacts(newContacts); } - deleteContact(contact: Contact) { + deleteContact(contact: ViewReadyContact) { const newContacts = this.contacts().filter((c) => c !== contact); return this.saveContacts(newContacts); } diff --git a/console-webapp/src/app/settings/contact/contactDetails.component.html b/console-webapp/src/app/settings/contact/contactDetails.component.html index 7b0248046..ea206a03f 100644 --- a/console-webapp/src/app/settings/contact/contactDetails.component.html +++ b/console-webapp/src/app/settings/contact/contactDetails.component.html @@ -1,104 +1,201 @@ -

Contact details

-
-
-

- +

+
+ +
+ @if(!isEditing && !contactService.isContactNewView) { + + + } +
+ + @if(isEditing || contactService.isContactNewView) { +

Contact Details

+ +
+ Name: -

-

- + Primary account email: -

-

- + Phone: -

-

- + Fax: -

+
-
- -
+
+

Contact Type

+

+ errorRequired to select at least one +

+
- {{ contactType.label }} + {{ contactType.value }}
-
- -
- Show in Registrar WHOIS record as admin contact
- Show in Registrar WHOIS record as technical contact -
+

WHOIS Preferences

+
+ Show in Registrar WHOIS record as admin contact +
-
- Show Phone and Email in Domain WHOIS Record as registrar abuse contact - (per CL&D requirements) +
+ Show in Registrar WHOIS record as technical contact +
+ +
+ Show Phone and Email in Domain WHOIS Record as registrar abuse + contact (per CL&D requirements) +
- - - - + + } @else { +

{{ contactService.contactInEdit.name }}

+ + + + +

Contact details

+
+ + + Email + {{ + contactService.contactInEdit.emailAddress + }} + + + + Phone + {{ + contactService.contactInEdit.phoneNumber + }} + + + + Fax + {{ + contactService.contactInEdit.faxNumber + }} + + + + Type: + {{ + contactService.contactInEdit.userFriendlyTypes.join(", ") + }} + +
+
+
+ + + + +

WHOIS Preferences

+
+ @if(contactService.contactInEdit.visibleInWhoisAsAdmin) { + + + Show in Registrar WHOIS record as admin contact + + } @if(contactService.contactInEdit.visibleInWhoisAsTech) { + + + Show in Registrar WHOIS record as technical contact + + } @if(contactService.contactInEdit.visibleInDomainWhoisAsAbuse) { + + + Show Phone and Email in Domain WHOIS Record as registrar abuse + contact (per CL&D requirements) + + } +
+
+
+ }
diff --git a/console-webapp/src/app/settings/contact/contactDetails.component.scss b/console-webapp/src/app/settings/contact/contactDetails.component.scss new file mode 100644 index 000000000..d0076d0ff --- /dev/null +++ b/console-webapp/src/app/settings/contact/contactDetails.component.scss @@ -0,0 +1,31 @@ +.console-app__contact { + max-width: 616px; + section { + margin-bottom: 40px; + } + &-required { + display: flex; + align-items: center; + gap: 10px; + } + + &-submit { + margin: 30px 0; + } + + &-controls { + display: flex; + align-items: center; + margin: 20px 0; + } + + mat-card { + margin-bottom: 30px; + } + + mat-form-field { + display: block; + width: 100%; + margin-bottom: 30px; + } +} diff --git a/console-webapp/src/app/settings/contact/contactDetails.component.ts b/console-webapp/src/app/settings/contact/contactDetails.component.ts new file mode 100644 index 000000000..9754c87af --- /dev/null +++ b/console-webapp/src/app/settings/contact/contactDetails.component.ts @@ -0,0 +1,103 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { HttpErrorResponse } from '@angular/common/http'; +import { Component } from '@angular/core'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { first } from 'rxjs'; +import { + ContactService, + contactType, + contactTypeToTextMap, +} from './contact.service'; + +@Component({ + selector: 'app-contact-details', + templateUrl: './contactDetails.component.html', + styleUrls: ['./contactDetails.component.scss'], +}) +export class ContactDetailsComponent { + protected contactTypeToTextMap = contactTypeToTextMap; + isEditing: boolean = false; + + constructor( + protected contactService: ContactService, + private _snackBar: MatSnackBar + ) {} + + deleteContact() { + if ( + confirm( + `Please confirm deletion of contact ${this.contactService.contactInEdit.name}` + ) + ) { + this.contactService + .deleteContact(this.contactService.contactInEdit) + .pipe(first()) + .subscribe({ + error: (err: HttpErrorResponse) => { + this._snackBar.open(err.error); + }, + }); + } + } + + goBack() { + if (this.isEditing) { + this.isEditing = false; + } else { + this.contactService.isContactNewView = false; + this.contactService.isContactDetailsView = false; + } + } + + save(e: SubmitEvent) { + e.preventDefault(); + this.contactService + .saveContacts([this.contactService.contactInEdit]) + .subscribe({ + complete: () => { + this.goBack(); + }, + error: (err: HttpErrorResponse) => { + this._snackBar.open(err.error); + }, + }); + } + + checkboxIsChecked(type: string) { + return this.contactService.contactInEdit.types.includes( + type as contactType + ); + } + + checkboxIsDisabled(type: string) { + return ( + this.contactService.contactInEdit.types.length === 1 && + this.contactService.contactInEdit.types[0] === (type as contactType) + ); + } + + checkboxOnChange(event: MatCheckboxChange, type: string) { + if (event.checked) { + this.contactService.contactInEdit.types.push(type as contactType); + } else { + this.contactService.contactInEdit.types = + this.contactService.contactInEdit.types.filter( + (t) => t != (type as contactType) + ); + } + } +} diff --git a/console-webapp/src/app/settings/security/security.component.html b/console-webapp/src/app/settings/security/security.component.html index a517e8eb4..25bdbc9f7 100644 --- a/console-webapp/src/app/settings/security/security.component.html +++ b/console-webapp/src/app/settings/security/security.component.html @@ -1,98 +1,82 @@ -
- -
-
-
-
-

IP Allowlist

-

- Restrict access to EPP production servers to the following IP/IPv6 - addresses, or ranges like 1.1.1.0/24 -

-
-
-
-
- - +@if(securityService.isEditingSecurity) { + +} @else { +
+ + + + + +
+

IP Allowlist

- -
-
- -
-
-
-
-

SSL Certificate

-

X.509 PEM certificate for EPP production access.

-
-
- -
-
-
-
-

Failover SSL Certificate

-

X.509 PEM backup certificate for EPP Production Access.

-
-
- -
-
-
- - - - - - - -
+
+ + + Restrict access to EPP production servers to the following IP/IPv6 + addresses, or ranges like 1.1.1.0/24 + + + @for (item of dataSource.ipAddressAllowList; track item.value) { + + {{ item.value }} + + + } @empty { + + No IP addresses on file. + + } + + + + + +

SSL Certificate

+
+ + X.509 PEM certificate for EPP production access + + + + {{ + dataSource.clientCertificate || "No client certificate on file." + }} + + + + + + +

Failover SSL Certificate

+
+ + X.509 PEM backup certificate for EPP production access + + + + {{ + dataSource.failoverClientCertificate || + "No failover certificate on file." + }} + + + + +
+} diff --git a/console-webapp/src/app/settings/security/security.component.scss b/console-webapp/src/app/settings/security/security.component.scss index 674ae37d6..ffe5a70a2 100644 --- a/console-webapp/src/app/settings/security/security.component.scss +++ b/console-webapp/src/app/settings/security/security.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,41 +13,14 @@ // limitations under the License. .settings-security { - margin-top: 1.5rem; - h1 { - margin: 0; + max-width: 616px; + mat-card { + margin-bottom: 40px; } - &__ipRecord { - margin-bottom: 1rem; - } - &__section { + &__section-header { display: flex; - align-items: stretch; - margin-bottom: 3rem; - flex-wrap: wrap; - } - &__section-description { - flex: 1; - min-width: 300px; - } - &__section-form { - flex: 1; - min-width: 300px; - textarea { - min-height: 100%; - min-width: 100%; - box-sizing: border-box; - min-height: 100px; - } - } - &__actions { - display: flex; - justify-content: flex-end; - button { - margin-left: 20px; - } - } - &__loading { - margin: 2rem 0; + justify-content: space-between; + align-items: center; + width: 100%; } } diff --git a/console-webapp/src/app/settings/security/security.component.spec.ts b/console-webapp/src/app/settings/security/security.component.spec.ts index 468d3a25a..d26b93b2d 100644 --- a/console-webapp/src/app/settings/security/security.component.spec.ts +++ b/console-webapp/src/app/settings/security/security.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/security/security.component.ts b/console-webapp/src/app/settings/security/security.component.ts index d9d352627..770f5c567 100644 --- a/console-webapp/src/app/settings/security/security.component.ts +++ b/console-webapp/src/app/settings/security/security.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,70 +12,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component } from '@angular/core'; +import { Component, effect } from '@angular/core'; +import { RegistrarService } from 'src/app/registrar/registrar.service'; import { SecurityService, SecuritySettings, apiToUiConverter, } from './security.service'; -import { HttpErrorResponse } from '@angular/common/http'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { RegistrarService } from 'src/app/registrar/registrar.service'; @Component({ selector: 'app-security', templateUrl: './security.component.html', styleUrls: ['./security.component.scss'], - providers: [SecurityService], }) export default class SecurityComponent { public static PATH = 'security'; - - loading: boolean = false; - inEdit: boolean = false; dataSource: SecuritySettings = {}; - constructor( public securityService: SecurityService, - private _snackBar: MatSnackBar, public registrarService: RegistrarService ) { - this.dataSource = apiToUiConverter(this.registrarService.registrar()); - } - - enableEdit() { - this.inEdit = true; - } - - cancel() { - this.inEdit = false; - this.resetDataSource(); - } - - createIpEntry() { - this.dataSource.ipAddressAllowList?.push({ value: '' }); - } - - save() { - this.loading = true; - this.securityService.saveChanges(this.dataSource).subscribe({ - complete: () => { - this.loading = false; - this.resetDataSource(); - }, - error: (err: HttpErrorResponse) => { - this._snackBar.open(err.error); - }, + effect(() => { + if (this.registrarService.registrar()) { + this.dataSource = apiToUiConverter(this.registrarService.registrar()); + this.securityService.isEditingSecurity = false; + } }); - this.cancel(); } - removeIpEntry(index: number) { - this.dataSource.ipAddressAllowList = - this.dataSource.ipAddressAllowList?.filter((_, i) => i != index); - } - - resetDataSource() { - this.dataSource = apiToUiConverter(this.registrarService.registrar()); + editSecurity() { + this.securityService.isEditingSecurity = true; } } diff --git a/console-webapp/src/app/settings/security/security.service.spec.ts b/console-webapp/src/app/settings/security/security.service.spec.ts index 578423e78..c71354a28 100644 --- a/console-webapp/src/app/settings/security/security.service.spec.ts +++ b/console-webapp/src/app/settings/security/security.service.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/security/security.service.ts b/console-webapp/src/app/settings/security/security.service.ts index a6c057980..16e96b298 100644 --- a/console-webapp/src/app/settings/security/security.service.ts +++ b/console-webapp/src/app/settings/security/security.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ import { switchMap } from 'rxjs'; import { RegistrarService } from 'src/app/registrar/registrar.service'; import { BackendService } from 'src/app/shared/services/backend.service'; -interface ipAllowListItem { +export interface ipAllowListItem { value: string; } export interface SecuritySettings { @@ -52,9 +52,12 @@ export function uiToApiConverter( }); } -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class SecurityService { securitySettings: SecuritySettings = {}; + isEditingSecurity: boolean = false; constructor( private backend: BackendService, diff --git a/console-webapp/src/app/settings/security/securityEdit.component.html b/console-webapp/src/app/settings/security/securityEdit.component.html new file mode 100644 index 000000000..95140db28 --- /dev/null +++ b/console-webapp/src/app/settings/security/securityEdit.component.html @@ -0,0 +1,60 @@ +
+

IP Allowlist

+

+ Restrict access to EPP production servers to the following IP/IPv6 + addresses, or ranges like 1.1.1.0/24 +

+
+ @for (ip of dataSource.ipAddressAllowList; track ip.value) { +
+ + + + +
+ } + + +

SSL Certificate

+

X.509 PEM certificate for EPP production access.

+ + + +

Failover SSL Certificate

+

X.509 PEM backup certificate for EPP Production Access.

+ + + + +
+
diff --git a/console-webapp/src/app/home/widgets/promotionsWidget.component.ts b/console-webapp/src/app/settings/security/securityEdit.component.scss similarity index 62% rename from console-webapp/src/app/home/widgets/promotionsWidget.component.ts rename to console-webapp/src/app/settings/security/securityEdit.component.scss index 43752d5c0..9b4312905 100644 --- a/console-webapp/src/app/home/widgets/promotionsWidget.component.ts +++ b/console-webapp/src/app/settings/security/securityEdit.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,12 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component } from '@angular/core'; - -@Component({ - selector: '[app-promotions-widget]', - templateUrl: './promotionsWidget.component.html', -}) -export class PromotionsWidgetComponent { - constructor() {} +.settings-security__edit { + max-width: 616px; + h1 { + margin-top: 30px; + } + mat-form-field { + width: 100%; + flex: 1; + } + &-ip { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; + } + &-save { + margin-top: 30px; + } } diff --git a/console-webapp/src/app/settings/security/securityEdit.component.ts b/console-webapp/src/app/settings/security/securityEdit.component.ts new file mode 100644 index 000000000..e2f8deb47 --- /dev/null +++ b/console-webapp/src/app/settings/security/securityEdit.component.ts @@ -0,0 +1,65 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { HttpErrorResponse } from '@angular/common/http'; +import { Component } from '@angular/core'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { RegistrarService } from 'src/app/registrar/registrar.service'; +import { + SecurityService, + SecuritySettings, + apiToUiConverter, + ipAllowListItem, +} from './security.service'; + +@Component({ + selector: 'app-security-edit', + templateUrl: './securityEdit.component.html', + styleUrls: ['./securityEdit.component.scss'], +}) +export default class SecurityEditComponent { + dataSource: SecuritySettings = {}; + + constructor( + public securityService: SecurityService, + private _snackBar: MatSnackBar, + public registrarService: RegistrarService + ) { + this.dataSource = apiToUiConverter(registrarService.registrar()); + } + + createIpEntry() { + this.dataSource.ipAddressAllowList?.push({ value: '' }); + } + + save() { + this.securityService.saveChanges(this.dataSource).subscribe({ + complete: () => { + this.goBack(); + }, + error: (err: HttpErrorResponse) => { + this._snackBar.open(err.error); + }, + }); + } + + goBack() { + this.securityService.isEditingSecurity = false; + } + + removeIpEntry(ip: ipAllowListItem) { + this.dataSource.ipAddressAllowList = + this.dataSource.ipAddressAllowList?.filter((item) => item !== ip); + } +} diff --git a/console-webapp/src/app/settings/settings.component.html b/console-webapp/src/app/settings/settings.component.html index 540e27eef..c2871a288 100644 --- a/console-webapp/src/app/settings/settings.component.html +++ b/console-webapp/src/app/settings/settings.component.html @@ -1,24 +1,37 @@ -
-

Settings

- + + + + +
+ diff --git a/console-webapp/src/app/settings/settings.component.scss b/console-webapp/src/app/settings/settings.component.scss index afae0f193..a530022eb 100644 --- a/console-webapp/src/app/settings/settings.component.scss +++ b/console-webapp/src/app/settings/settings.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,6 +13,9 @@ // limitations under the License. .console-settings { + > mat-divider { + margin-bottom: 40px; + } .mdc-tab { &.active-link { border-bottom: 2px solid var(--primary); diff --git a/console-webapp/src/app/settings/settings.component.spec.ts b/console-webapp/src/app/settings/settings.component.spec.ts index 128d15192..976bc5845 100644 --- a/console-webapp/src/app/settings/settings.component.spec.ts +++ b/console-webapp/src/app/settings/settings.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/settings.component.ts b/console-webapp/src/app/settings/settings.component.ts index 5e7cdbd67..ad0c77d48 100644 --- a/console-webapp/src/app/settings/settings.component.ts +++ b/console-webapp/src/app/settings/settings.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,4 +22,10 @@ import { Component, ViewEncapsulation } from '@angular/core'; }) export class SettingsComponent { public static PATH = 'settings'; + + public static matchesUrl(url: string): boolean { + return url[0] === '/' + ? url.startsWith(`/${this.PATH}`) + : url.startsWith(this.PATH); + } } diff --git a/console-webapp/src/app/settings/users/users.component.scss b/console-webapp/src/app/settings/users/users.component.scss index 5b5b64371..c5e3ba122 100644 --- a/console-webapp/src/app/settings/users/users.component.scss +++ b/console-webapp/src/app/settings/users/users.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/users/users.component.spec.ts b/console-webapp/src/app/settings/users/users.component.spec.ts index 95b89f54c..6ab79ebe6 100644 --- a/console-webapp/src/app/settings/users/users.component.spec.ts +++ b/console-webapp/src/app/settings/users/users.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/users/users.component.ts b/console-webapp/src/app/settings/users/users.component.ts index 5828ce4ee..6c97691b6 100644 --- a/console-webapp/src/app/settings/users/users.component.ts +++ b/console-webapp/src/app/settings/users/users.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/whois/whois.component.html b/console-webapp/src/app/settings/whois/whois.component.html index c14215e5c..b3e074893 100644 --- a/console-webapp/src/app/settings/whois/whois.component.html +++ b/console-webapp/src/app/settings/whois/whois.component.html @@ -1,244 +1,105 @@ -
-

WHOIS settings

-

- General registrar information for your WHOIS record. This information is - always visible in WHOIS. -

-
- -
-
-
-

Name:

-
-
- - - -
-
-
-
-

IANA Identifier:

-
-
- - - -
-
-
-
-

ICANN Referral Email:

-
-
- - - -
-
-
-
-

WHOIS server:

-
-
- - - -
-
-
-
-

Referral URL:

-
-
- - - -
-
-
-
-

Email:

-
-
- - - -
-
-
-
-

Phone::

-
-
- - - -
-
-
-
-

Fax:

-
-
- - - -
-
-
-
-
-

Address Line 1:

-
-
- - - -
-
-
-
-

City:

-
-
- - - -
-
-
-
-
-
-

Address Line 2:

-
-
- - - -
-
-
-
-

State/Region:

-
-
- - - -
-
-
-
-
-
-

Address Line 3:

-
-
- - - -
-
-
-
-

Country Code:

-
-
- - - -
-
-
-
- - - - - - - +@if(whoisService.editing) { + +} @else { +
+
+ + General registrar information for your WHOIS record. This information is + always visible in WHOIS. + +
+
+ + + + + +

Personal Info

+
+ + + Company name + {{ + registrarService.registrar()?.registrarName + }} + + + + Referral email + {{ + registrarService.registrar()?.emailAddress + }} + + + + Phone + {{ + registrarService.registrar()?.phoneNumber + }} + + + + Fax + {{ + registrarService.registrar()?.faxNumber + }} + + + + Address + {{ formattedAddress() }} + +
+
+
+ + + + + +

Technical Info

+
+ + + IANA Identifier + {{ + registrarService.registrar()?.ianaIdentifier + }} + + + +
+ ICANN Referral Email + {{ + registrarService.registrar()?.icannReferralEmail + }} +
+
+ + + WHOIS server + {{ + registrarService.registrar()?.whoisServer + }} + + + + Referral URL + {{ + registrarService.registrar()?.url + }} + +
+
+
+} diff --git a/console-webapp/src/app/settings/whois/whois.component.scss b/console-webapp/src/app/settings/whois/whois.component.scss index 6d08212c8..538dec1db 100644 --- a/console-webapp/src/app/settings/whois/whois.component.scss +++ b/console-webapp/src/app/settings/whois/whois.component.scss @@ -1,59 +1,17 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +.console-app__whois { + max-width: 616px; -.settings-whois { - margin-top: 1.5rem; - &__section { + &-controls { display: flex; - flex-wrap: wrap; - margin-bottom: 10px; - min-width: 400px; - } - &__section-address { - display: flex; - flex-wrap: wrap; - margin-bottom: 5px; - min-width: 400px; - width: 50%; - max-width: 50%; - } - &__section-description { - display: inline-block; - margin-block-start: 1em; - width: 160px; - } - &__section-form { - display: inline-block; - width: 70%; - mat-form-field { - width: 90%; - min-width: 300px; - } - input:disabled { - border: 0; - } - } - &__loading { - margin: 2rem 0; - } - &__actions { - margin-top: 50px; - display: flex; - justify-content: flex-end; - margin-right: 50px; + align-items: center; + gap: 1rem; + margin: 20px 0; button { - margin-left: 20px; + flex-shrink: 0; } } + + mat-card { + margin-bottom: 30px; + } } diff --git a/console-webapp/src/app/settings/whois/whois.component.spec.ts b/console-webapp/src/app/settings/whois/whois.component.spec.ts index 994b44777..00434b3d6 100644 --- a/console-webapp/src/app/settings/whois/whois.component.spec.ts +++ b/console-webapp/src/app/settings/whois/whois.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/settings/whois/whois.component.ts b/console-webapp/src/app/settings/whois/whois.component.ts index a0891a6b2..565549969 100644 --- a/console-webapp/src/app/settings/whois/whois.component.ts +++ b/console-webapp/src/app/settings/whois/whois.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,13 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { HttpErrorResponse } from '@angular/common/http'; -import { Component } from '@angular/core'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { - Registrar, - RegistrarService, -} from 'src/app/registrar/registrar.service'; +import { Component, computed } from '@angular/core'; +import { RegistrarService } from 'src/app/registrar/registrar.service'; import { WhoisService } from './whois.service'; @@ -26,51 +21,29 @@ import { WhoisService } from './whois.service'; selector: 'app-whois', templateUrl: './whois.component.html', styleUrls: ['./whois.component.scss'], - providers: [WhoisService], }) export default class WhoisComponent { public static PATH = 'whois'; - loading = false; - inEdit = false; - registrar: Registrar; + formattedAddress = computed(() => { + let result = ''; + const registrar = this.registrarService.registrar(); + if (registrar?.localizedAddress?.street) { + result += `${registrar?.localizedAddress?.street?.join(' ')} `; + } + if (registrar?.localizedAddress?.city) { + result += `${registrar?.localizedAddress?.city} `; + } + if (registrar?.localizedAddress?.state) { + result += `${registrar?.localizedAddress?.state} `; + } + if (registrar?.localizedAddress?.street) { + result += registrar?.localizedAddress?.countryCode; + } + return result; + }); constructor( public whoisService: WhoisService, - public registrarService: RegistrarService, - private _snackBar: MatSnackBar - ) { - this.registrar = JSON.parse( - JSON.stringify(this.registrarService.registrar) - ); - } - - enableEdit() { - this.inEdit = true; - } - - cancel() { - this.inEdit = false; - this.resetDataSource(); - } - - save() { - this.loading = true; - this.whoisService.saveChanges(this.registrar).subscribe({ - complete: () => { - this.loading = false; - this.resetDataSource(); - }, - error: (err: HttpErrorResponse) => { - this._snackBar.open(err.error); - this.loading = false; - }, - }); - this.cancel(); - } - - resetDataSource() { - this.registrar = JSON.parse( - JSON.stringify(this.registrarService.registrar) - ); - } + public registrarService: RegistrarService + ) {} } diff --git a/console-webapp/src/app/settings/whois/whois.service.ts b/console-webapp/src/app/settings/whois/whois.service.ts index 54e99202f..18de759ec 100644 --- a/console-webapp/src/app/settings/whois/whois.service.ts +++ b/console-webapp/src/app/settings/whois/whois.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,21 +14,17 @@ import { Injectable } from '@angular/core'; import { switchMap } from 'rxjs'; -import { Address, RegistrarService } from 'src/app/registrar/registrar.service'; +import { + RegistrarService, + WhoisRegistrarFields, +} from 'src/app/registrar/registrar.service'; import { BackendService } from 'src/app/shared/services/backend.service'; -export interface WhoisRegistrarFields { - ianaIdentifier?: number; - icannReferralEmail?: string; - localizedAddress?: Address; - registrarId?: string; - url?: string; - whoisServer?: string; -} - -@Injectable() +@Injectable({ + providedIn: 'root', +}) export class WhoisService { - whoisRegistrarFields: WhoisRegistrarFields = {}; + editing: boolean = false; constructor( private backend: BackendService, diff --git a/console-webapp/src/app/settings/whois/whoisEdit.component.html b/console-webapp/src/app/settings/whois/whoisEdit.component.html new file mode 100644 index 000000000..1813af845 --- /dev/null +++ b/console-webapp/src/app/settings/whois/whoisEdit.component.html @@ -0,0 +1,128 @@ +
+ + +
+ + General registrar information for your WHOIS record. This information is + always visible in WHOIS. + +
+
+ +
+

Personal info

+ +
+ + Email: + + + + + Phone: + + + + + Fax: + + + + + Street Address: + + + + + City: + + + + + State or Province: + + + + + Country: + + + + + Postal code: + + + +

Technical info

+ + + WHOIS server: + + + + + Referral URL: + + + + +
+
+
diff --git a/console-webapp/src/app/settings/whois/whoisEdit.component.scss b/console-webapp/src/app/settings/whois/whoisEdit.component.scss new file mode 100644 index 000000000..49c4fdd80 --- /dev/null +++ b/console-webapp/src/app/settings/whois/whoisEdit.component.scss @@ -0,0 +1,19 @@ +.console-app__whois-edit { + max-width: 616px; + + &-controls { + display: flex; + align-items: center; + gap: 1rem; + margin: 20px 0; + button { + flex-shrink: 0; + } + } + + mat-form-field { + display: block; + width: 100%; + margin-bottom: 30px; + } +} diff --git a/console-webapp/src/app/settings/whois/whoisEdit.component.ts b/console-webapp/src/app/settings/whois/whoisEdit.component.ts new file mode 100644 index 000000000..2f3d425ed --- /dev/null +++ b/console-webapp/src/app/settings/whois/whoisEdit.component.ts @@ -0,0 +1,58 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, effect } from '@angular/core'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { + Registrar, + RegistrarService, +} from 'src/app/registrar/registrar.service'; +import { WhoisService } from './whois.service'; + +@Component({ + selector: 'app-whois-edit', + templateUrl: './whoisEdit.component.html', + styleUrls: ['./whoisEdit.component.scss'], +}) +export default class WhoisEditComponent { + registrarInEdit: Registrar | undefined; + + constructor( + public whoisService: WhoisService, + public registrarService: RegistrarService, + private _snackBar: MatSnackBar + ) { + effect(() => { + const registrar = this.registrarService.registrar(); + if (registrar) { + this.registrarInEdit = structuredClone(registrar); + } + }); + } + + save(e: SubmitEvent) { + e.preventDefault(); + if (!this.registrarInEdit) return; + + this.whoisService.saveChanges(this.registrarInEdit).subscribe({ + complete: () => { + this.whoisService.editing = false; + }, + error: (err: HttpErrorResponse) => { + this._snackBar.open(err.error); + }, + }); + } +} diff --git a/console-webapp/src/app/shared/components/dialogBottomSheet.component.ts b/console-webapp/src/app/shared/components/dialogBottomSheet.component.ts deleted file mode 100644 index 73ad95afd..000000000 --- a/console-webapp/src/app/shared/components/dialogBottomSheet.component.ts +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { BreakpointObserver } from '@angular/cdk/layout'; -import { ComponentType } from '@angular/cdk/portal'; -import { Component } from '@angular/core'; -import { - MatBottomSheet, - MatBottomSheetRef, -} from '@angular/material/bottom-sheet'; -import { MatDialog, MatDialogRef } from '@angular/material/dialog'; - -const MOBILE_LAYOUT_BREAKPOINT = '(max-width: 599px)'; - -export interface DialogBottomSheetContent { - init(data: Object): void; -} - -/** - * Wraps up a child component in an Angular Material Dalog for desktop or a Bottom Sheet - * component for mobile depending on a screen resolution, with Breaking Point being 599px. - * Child component is required to implement @see DialogBottomSheetContent interface - */ -@Component({ - selector: 'app-dialog-bottom-sheet-wrapper', - template: '', -}) -export class DialogBottomSheetWrapper { - private elementRef?: MatBottomSheetRef | MatDialogRef; - - constructor( - private dialog: MatDialog, - private bottomSheet: MatBottomSheet, - protected breakpointObserver: BreakpointObserver - ) {} - - open( - component: ComponentType, - data: any - ) { - const config = { data, close: () => this.close() }; - if (this.breakpointObserver.isMatched(MOBILE_LAYOUT_BREAKPOINT)) { - this.elementRef = this.bottomSheet.open(component); - this.elementRef.instance.init(config); - } else { - this.elementRef = this.dialog.open(component); - this.elementRef.componentInstance.init(config); - } - } - - close() { - if (this.elementRef instanceof MatBottomSheetRef) { - this.elementRef.dismiss(); - } else if (this.elementRef instanceof MatDialogRef) { - this.elementRef.close(); - } - } -} diff --git a/console-webapp/src/app/shared/components/notifications/notifications.component.html b/console-webapp/src/app/shared/components/notifications/notifications.component.html new file mode 100644 index 000000000..29c7fa902 --- /dev/null +++ b/console-webapp/src/app/shared/components/notifications/notifications.component.html @@ -0,0 +1,16 @@ +
+ @for (notification of mockNotifications; track notification.id) { +
+
+ +

{{ notification.text }}

+
+ + +
+ } +
diff --git a/console-webapp/src/app/shared/components/notifications/notifications.component.scss b/console-webapp/src/app/shared/components/notifications/notifications.component.scss new file mode 100644 index 000000000..06ad7ecc5 --- /dev/null +++ b/console-webapp/src/app/shared/components/notifications/notifications.component.scss @@ -0,0 +1,23 @@ +.console-app { + &__notifications { + margin-bottom: 40px; + } + &__notification { + padding: 20px; + background-color: var(--lightest); + border-radius: 10px; + margin-bottom: 10px; + display: flex; + justify-content: space-between; + align-items: center; + &-content { + display: flex; + align-items: center; + gap: 10px; + } + h4 { + margin: 0; + padding: 0; + } + } +} diff --git a/console-webapp/src/app/home/widgets/domainsWidget.component.ts b/console-webapp/src/app/shared/components/notifications/notifications.component.ts similarity index 55% rename from console-webapp/src/app/home/widgets/domainsWidget.component.ts rename to console-webapp/src/app/shared/components/notifications/notifications.component.ts index aaa1e0a54..69b89be32 100644 --- a/console-webapp/src/app/home/widgets/domainsWidget.component.ts +++ b/console-webapp/src/app/shared/components/notifications/notifications.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,17 +13,25 @@ // limitations under the License. import { Component } from '@angular/core'; -import { Router } from '@angular/router'; -import { DomainListComponent } from 'src/app/domains/domainList.component'; + +interface Notification { + id: string; + date: Date; + text: string; +} @Component({ - selector: '[app-domains-widget]', - templateUrl: './domainsWidget.component.html', + selector: 'app-notifications', + templateUrl: './notifications.component.html', + styleUrls: ['./notifications.component.scss'], }) -export class DomainsWidgetComponent { - constructor(private router: Router) {} - - openDomainsPage() { - this.router.navigate([DomainListComponent.PATH]); - } +export class NotificationsComponent { + protected mockNotifications: Notification[] = [ + { + id: '0', + date: new Date(), + text: 'Registry Downtime Planned on June 9, 2024 due to maintenance.', + }, + ]; + constructor() {} } diff --git a/console-webapp/src/app/registrar/emptyRegistrar.component.scss b/console-webapp/src/app/shared/components/selectedRegistrarWrapper/selectedRegistrarWrapper.component.scss similarity index 100% rename from console-webapp/src/app/registrar/emptyRegistrar.component.scss rename to console-webapp/src/app/shared/components/selectedRegistrarWrapper/selectedRegistrarWrapper.component.scss diff --git a/console-webapp/src/app/shared/components/selectedRegistrarWrapper/selectedRegistrarWrapper.component.ts b/console-webapp/src/app/shared/components/selectedRegistrarWrapper/selectedRegistrarWrapper.component.ts new file mode 100644 index 000000000..87ebb4e51 --- /dev/null +++ b/console-webapp/src/app/shared/components/selectedRegistrarWrapper/selectedRegistrarWrapper.component.ts @@ -0,0 +1,37 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component } from '@angular/core'; +import { RegistrarService } from 'src/app/registrar/registrar.service'; + +@Component({ + selector: 'app-selected-registrar-wrapper', + styleUrls: ['./selectedRegistrarWrapper.component.scss'], + template: ` + @if(registrarService.registrarId()){ + + } @else { +
+

+ block +

+

No registrar selected

+

Please select a registrar

+
+ } + `, +}) +export class SelectedRegistrarWrapper { + constructor(protected registrarService: RegistrarService) {} +} diff --git a/console-webapp/src/app/home/widgets/tldsWidget.component.ts b/console-webapp/src/app/shared/directives/locationBack.directive.ts similarity index 61% rename from console-webapp/src/app/home/widgets/tldsWidget.component.ts rename to console-webapp/src/app/shared/directives/locationBack.directive.ts index 8f560632a..ccb6fc92f 100644 --- a/console-webapp/src/app/home/widgets/tldsWidget.component.ts +++ b/console-webapp/src/app/shared/directives/locationBack.directive.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component } from '@angular/core'; +import { Location } from '@angular/common'; +import { Directive, HostListener } from '@angular/core'; -@Component({ - selector: '[app-tlds-widget]', - templateUrl: './tldsWidget.component.html', +@Directive({ + selector: '[backButton]', }) -export class TldsWidgetComponent { - constructor() {} +export class LocationBackDirective { + constructor(private location: Location) {} + + @HostListener('click') + onClick() { + this.location.back(); + } } diff --git a/console-webapp/src/app/shared/services/backend.service.ts b/console-webapp/src/app/shared/services/backend.service.ts index c6c977a6a..fc81a0fd5 100644 --- a/console-webapp/src/app/shared/services/backend.service.ts +++ b/console-webapp/src/app/shared/services/backend.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,14 +14,16 @@ import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { catchError, Observable, of } from 'rxjs'; +import { Observable, catchError, of, throwError } from 'rxjs'; import { SecuritySettingsBackendModel } from 'src/app/settings/security/security.service'; -import { Contact } from '../../settings/contact/contact.service'; -import { Registrar } from '../../registrar/registrar.service'; -import { UserData } from './userData.service'; -import { WhoisRegistrarFields } from 'src/app/settings/whois/whois.service'; import { DomainListResult } from 'src/app/domains/domainList.service'; +import { + Registrar, + WhoisRegistrarFields, +} from '../../registrar/registrar.service'; +import { Contact } from '../../settings/contact/contact.service'; +import { UserData } from './userData.service'; @Injectable() export class BackendService { @@ -42,8 +44,11 @@ export class BackendService { ); } - // return throwError(() => {throw "Failed"}); - return of(mockData); + if (mockData) { + return of(mockData); + } else { + return throwError(() => error); + } } getContacts(registrarId: string): Observable { @@ -99,6 +104,12 @@ export class BackendService { .pipe(catchError((err) => this.errorCatcher(err))); } + postRegistrar(registrar: Registrar): Observable { + return this.http + .post('/console-api/registrar', registrar) + .pipe(catchError((err) => this.errorCatcher(err))); + } + getSecuritySettings( registrarId: string ): Observable { diff --git a/console-webapp/src/app/shared/services/breakPoint.service.ts b/console-webapp/src/app/shared/services/breakPoint.service.ts new file mode 100644 index 000000000..57afbb116 --- /dev/null +++ b/console-webapp/src/app/shared/services/breakPoint.service.ts @@ -0,0 +1,45 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { BreakpointObserver } from '@angular/cdk/layout'; +import { Injectable, signal } from '@angular/core'; +import { distinctUntilChanged } from 'rxjs'; + +const MOBILE_LAYOUT_BREAKPOINT = '(max-width: 560px)'; +const TABLET_LAYOUT_BREAKPOINT = '(max-width: 768px)'; + +@Injectable({ + providedIn: 'root', +}) +export class BreakPointObserverService { + isMobileView = signal(false); + isTabletView = signal(false); + + readonly breakpoint$ = this.breakpointObserver + .observe([MOBILE_LAYOUT_BREAKPOINT, TABLET_LAYOUT_BREAKPOINT]) + .pipe(distinctUntilChanged()); + + constructor(protected breakpointObserver: BreakpointObserver) { + this.breakpoint$.subscribe(() => this.breakpointChanged()); + } + + private breakpointChanged() { + this.isMobileView.set( + this.breakpointObserver.isMatched(MOBILE_LAYOUT_BREAKPOINT) + ); + this.isTabletView.set( + this.breakpointObserver.isMatched(TABLET_LAYOUT_BREAKPOINT) + ); + } +} diff --git a/console-webapp/src/app/shared/services/globalLoader.service.ts b/console-webapp/src/app/shared/services/globalLoader.service.ts index d8b0d7215..ed5354c39 100644 --- a/console-webapp/src/app/shared/services/globalLoader.service.ts +++ b/console-webapp/src/app/shared/services/globalLoader.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/shared/services/userData.service.ts b/console-webapp/src/app/shared/services/userData.service.ts index 0930cafbd..73d7d562d 100644 --- a/console-webapp/src/app/shared/services/userData.service.ts +++ b/console-webapp/src/app/shared/services/userData.service.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,14 +13,16 @@ // limitations under the License. import { Injectable } from '@angular/core'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { Observable, tap } from 'rxjs'; import { BackendService } from './backend.service'; -import { MatSnackBar } from '@angular/material/snack-bar'; import { GlobalLoader, GlobalLoaderService } from './globalLoader.service'; export interface UserData { globalRole: string; isAdmin: boolean; + // TODO: provide passcode from back-end + passcode?: string; productName: string; supportEmail: string; supportPhoneNumber: string; @@ -31,7 +33,7 @@ export interface UserData { providedIn: 'root', }) export class UserDataService implements GlobalLoader { - public userData?: UserData; + public userData!: UserData; constructor( private backend: BackendService, protected globalLoader: GlobalLoaderService, diff --git a/console-webapp/src/app/snackbar.module.ts b/console-webapp/src/app/snackbar.module.ts index 72fc4219e..81993c408 100644 --- a/console-webapp/src/app/snackbar.module.ts +++ b/console-webapp/src/app/snackbar.module.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/support/support.component.html b/console-webapp/src/app/support/support.component.html new file mode 100644 index 000000000..f25513a35 --- /dev/null +++ b/console-webapp/src/app/support/support.component.html @@ -0,0 +1,45 @@ +
+

Support

+

+ Our support team can assist you with any technical or operational questions + you may have regarding our registry services. +

+ +

Email

+

+ For help with OT&E sandbox and certification, or new technical requirements + for any of our new TLD launches. +

+ registry-integration@google.com +

+ For general purpose questions once you are integrated with our registry + system. If the issue is urgent, please put "Urgent" in the email title. +

+ {{ + userDataService.userData.supportEmail + }} +

+ Note: You may receive occasional service announcements via + registrar-announcement@google.com. You will not be able to reply to + those messages. +

+

Phone

+

For general support inquiries 24/7:

+ {{ userDataService.userData.supportPhoneNumber }} + @if (userDataService.userData.passcode) { +

Your telephone passcode:

+

+ {{ userDataService.userData.passcode }} +

+

+ Note: Please be ready with your account name and telephone passcode when + contacting us by phone. +

+ } +
diff --git a/console-webapp/src/app/support/support.component.scss b/console-webapp/src/app/support/support.component.scss new file mode 100644 index 000000000..4b0fd67d4 --- /dev/null +++ b/console-webapp/src/app/support/support.component.scss @@ -0,0 +1,22 @@ +.console-app { + &__support { + max-width: 616px; + &-passcode { + color: #1e8e3e; + } + p { + margin: 20px 0; + } + a { + margin-bottom: 30px; + display: inline-block; + } + mat-divider { + margin-bottom: 30px; + } + .secondary-text { + margin-bottom: 50px; + margin-top: -20px; + } + } +} diff --git a/console-webapp/src/app/home/widgets/eppWidget.component.ts b/console-webapp/src/app/support/support.component.ts similarity index 62% rename from console-webapp/src/app/home/widgets/eppWidget.component.ts rename to console-webapp/src/app/support/support.component.ts index 36bb7b0f8..f51dd85ae 100644 --- a/console-webapp/src/app/home/widgets/eppWidget.component.ts +++ b/console-webapp/src/app/support/support.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,11 +13,14 @@ // limitations under the License. import { Component } from '@angular/core'; +import { UserDataService } from '../shared/services/userData.service'; @Component({ - selector: '[app-epp-widget]', - templateUrl: './eppWidget.component.html', + selector: 'app-support', + templateUrl: './support.component.html', + styleUrls: ['./support.component.scss'], }) -export class EppWidgetComponent { - constructor() {} +export class SupportComponent { + public static PATH = 'support'; + constructor(protected userDataService: UserDataService) {} } diff --git a/console-webapp/src/app/tlds/tlds.component.html b/console-webapp/src/app/tlds/tlds.component.html index 6eb9d3b31..fcb7066c3 100644 --- a/console-webapp/src/app/tlds/tlds.component.html +++ b/console-webapp/src/app/tlds/tlds.component.html @@ -1,47 +1 @@ -
- - .how - A place for thinkers, tinkerers, and knowledge seekers - - Onboarding Now - Marketing Materials - Visit get.how for more information - - -
- -
- - .soy - A place for thinkers, tinkerers, and knowledge seekers - - Onboarding Now - Marketing Materials - Visit iam.soy for more information - - -
+
diff --git a/console-webapp/src/app/tlds/tlds.component.scss b/console-webapp/src/app/tlds/tlds.component.scss index 3b51df472..6753521df 100644 --- a/console-webapp/src/app/tlds/tlds.component.scss +++ b/console-webapp/src/app/tlds/tlds.component.scss @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/tlds/tlds.component.spec.ts b/console-webapp/src/app/tlds/tlds.component.spec.ts index dbec70697..e90adf08a 100644 --- a/console-webapp/src/app/tlds/tlds.component.spec.ts +++ b/console-webapp/src/app/tlds/tlds.component.spec.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/app/tlds/tlds.component.ts b/console-webapp/src/app/tlds/tlds.component.ts index 0569536cb..a2e8dc9c1 100644 --- a/console-webapp/src/app/tlds/tlds.component.ts +++ b/console-webapp/src/app/tlds/tlds.component.ts @@ -1,4 +1,4 @@ -// Copyright 2023 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/assets/billing.png b/console-webapp/src/assets/billing.png new file mode 100644 index 000000000..2ce4e0f6d Binary files /dev/null and b/console-webapp/src/assets/billing.png differ diff --git a/console-webapp/src/assets/resources.png b/console-webapp/src/assets/resources.png new file mode 100644 index 000000000..8b249b539 Binary files /dev/null and b/console-webapp/src/assets/resources.png differ diff --git a/console-webapp/src/environments/environment.prod.ts b/console-webapp/src/environments/environment.prod.ts index b72f66ffa..6eaac9c4c 100644 --- a/console-webapp/src/environments/environment.prod.ts +++ b/console-webapp/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/environments/environment.ts b/console-webapp/src/environments/environment.ts index 3e92547cb..fbd741183 100644 --- a/console-webapp/src/environments/environment.ts +++ b/console-webapp/src/environments/environment.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/index.html b/console-webapp/src/index.html index 5100249c1..193a4b4fa 100644 --- a/console-webapp/src/index.html +++ b/console-webapp/src/index.html @@ -6,9 +6,9 @@ - + - + diff --git a/console-webapp/src/main.ts b/console-webapp/src/main.ts index 6c8d5bdbd..e238ed61e 100644 --- a/console-webapp/src/main.ts +++ b/console-webapp/src/main.ts @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/console-webapp/src/styles.scss b/console-webapp/src/styles.scss index 00d282c9e..b4740aece 100644 --- a/console-webapp/src/styles.scss +++ b/console-webapp/src/styles.scss @@ -1,4 +1,4 @@ -// Copyright 2022 The Nomulus Authors. All Rights Reserved. +// Copyright 2024 The Nomulus Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,7 +20,8 @@ body { } body { margin: 0; - font-family: Roboto, "Helvetica Neue", sans-serif; + font-family: "Google Sans", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important; } .text-center { @@ -28,54 +29,45 @@ body { } .console-app { - &__widget { - display: flex; - gap: 10px; - > a { - text-decoration: none; - color: initial; + .mat-headline-4 { + margin-top: 6px; + margin-bottom: 24px; + } + .spacer { + flex: 1; + } + h1 { + margin-bottom: 24px; + } + a { + text-decoration: none; + color: #1a73e8; + } + mat-list-item { + height: auto !important; + min-height: 48px; + padding: 10px 0; + --list-item-title-width: 140px; + h2 { + margin: 13px 0; } - > a[href=""] { - cursor: not-allowed; + .console-app__list-key { + font-weight: bold; + width: var(--list-item-title-width); + display: inline-block; + font-size: 14px; + white-space: pre-line; + color: #202124; + flex-shrink: 0; } - &-wrapper__wide { - grid-column: span 2; - } - &-link { - padding: 0 !important; - text-align: left; - min-width: auto !important; - height: min-content !important; - } - &-section-header { - font-weight: 500; - color: var(--primary) !important; - } - &-title { - color: var(--primary) !important; - text-align: center; - } - &-icon { + .console-app__list-value { + font-size: 14px; + white-space: pre-line; + word-break: break-all; color: var(--text); - font-size: 5rem; - line-height: 5rem; - height: 5rem !important; - width: 5rem !important; - } - &_left { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; - } - &_right { - flex: 1; - border-left: 1px solid var(--secondary); - padding-left: 20px; - .secondary-text { - margin-bottom: 0.3rem; - font-size: 0.8rem; - } } } + .mat-mdc-list-item-unscoped-content { + display: flex; + } } diff --git a/console-webapp/src/theme.scss b/console-webapp/src/theme.scss index 80a1013d3..28f770e6e 100644 --- a/console-webapp/src/theme.scss +++ b/console-webapp/src/theme.scss @@ -1,6 +1,47 @@ @use "sass:map"; +@use "sass:math"; @use "@angular/material" as mat; +$secondary-color: #80868b; +$border-color: #dadce0; +$hue-undefined: "undefined"; +$blue-palette: ( + 50: #e8f0fe, + 100: #d2e3fc, + 200: #aecbfa, + 300: #8ab4f8, + 400: #669df6, + 500: #4285f4, + 600: #1a73e8, + 700: #1967d2, + 800: #185abc, + 900: #174ea6, + A100: $hue-undefined, + A200: $hue-undefined, + A400: $hue-undefined, + A700: $hue-undefined, + contrast: ( + 50: #174ea6, + 100: #174ea6, + 200: #174ea6, + 300: #174ea6, + 400: #174ea6, + 500: white, + 600: white, + 700: white, + 800: white, + 900: white, + A100: $hue-undefined, + A200: $hue-undefined, + A400: $hue-undefined, + A700: $hue-undefined, + ), +); + +@function rem($valueInPixels, $rootbase: 16px) { + @return math.div($valueInPixels, $rootbase) * 1rem; +} + /** Copied from docs section **/ // Include the common styles for Angular Material. We include this here so that you only @@ -8,12 +49,6 @@ // Be sure that you only ever include this mixin once! @include mat.core(); -// Define the palettes for your theme using the Material Design palettes available in palette.scss -// (imported above). For each palette, you can optionally specify a default, lighter, and darker -// hue. Available color palettes: https://material.io/design/color/ -$theme-primary: mat.define-palette(mat.$indigo-palette); -$theme-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - // The warn palette is optional (defaults to red). $theme-warn: mat.define-palette(mat.$red-palette); @@ -21,6 +56,64 @@ $theme-warn: mat.define-palette(mat.$red-palette); ** Application specific section - Global styles and mixins **/ +$theme-primary: mat.define-palette($blue-palette); + +$typographyConfig: mat.define-typography-config( + $headline-1: + mat.define-typography-level( + rem(29px), + rem(36px), + 500, + "Google Sans", + normal + ), + $headline-4: + mat.define-typography-level( + rem(28px), + rem(36px), + 500, + "Google Sans", + normal + ), + $headline-5: + mat.define-typography-level( + rem(20px), + rem(28px), + 400, + "Google Sans", + normal + ), + $headline-6: + mat.define-typography-level(rem(16px), rem(2px), 500, "Google Sans", normal), + $body-1: + mat.define-typography-level( + rem(16px), + rem(24px), + 400, + "Google Sans Text", + normal + ), + $body-2: + mat.define-typography-level( + rem(14px), + rem(20px), + 400, + "Google Sans Text", + normal + ), + $caption: + mat.define-typography-level( + rem(14px), + rem(24px), + 400, + "Google Sans", + 0.15px + ), + $overline: + mat.define-typography-level(rem(14px), rem(20px), 500, "Google Sans", 0.5px), +); + +@include mat.typography-hierarchy($typographyConfig); @mixin form-field-density($density) { $field-typography: mat.define-typography-config( $body-1: mat.define-typography-level(12px, 24px, 400), @@ -42,53 +135,42 @@ $light-theme: mat.define-light-theme( ( color: ( primary: $theme-primary, - accent: $theme-accent, + accent: $theme-primary, warn: $theme-warn, ), density: 0, + typography: $typographyConfig, ) ); // Access and define a class with secondary color exposed .secondary-text { - color: map.get(mat.$light-theme-foreground-palette, "secondary-text"); + color: $secondary-color; +} + +.text-xl { + font-size: 18px; +} +.text-l { + font-size: 16px; +} + +mat-row:nth-child(odd) { + background-color: var(--lightest-highlight); +} + +mat-row:hover { + background-color: $border-color; } :root { - --text: #{map.get(mat.$light-theme-foreground-palette, "base")}; - --primary: #{mat.get-color-from-palette($theme-primary, 500)}; - --secondary: #{map.get(mat.$light-theme-foreground-palette, "secondary-text")}; + --text: #5f6368; + --primary: #{mat.get-color-from-palette($blue-palette, 500)}; + --lightest: #{mat.get-color-from-palette($blue-palette, 100)}; + --light-highlight: #e8eaed; + --lightest-highlight: #f8f9fa; + --secondary: #{$secondary-color}; + --border: #{$border-color}; } @include mat.all-component-themes($light-theme); - -/** -** Dark theme -**/ -$dark-theme: mat.define-dark-theme( - ( - color: ( - primary: mat.define-palette(mat.$pink-palette), - accent: mat.define-palette(mat.$blue-grey-palette), - ), - density: 0, - ) -); - -@mixin _apply-dark-mode-colors() { - @include mat.all-component-colors($dark-theme); - - .secondary-text { - color: map.get(mat.$dark-theme-foreground-palette, "secondary-text"); - } - - :root { - --text: #{map.get(mat.$dark-theme-foreground-palette, "base")}; - --primary: #{mat.get-color-from-palette(mat.$pink-palette, 500)}; - --secondary: #{map.get(mat.$dark-theme-background-palette, "secondary-text")}; - } -} - -@media (prefers-color-scheme: dark) { - @include _apply-dark-mode-colors(); -} diff --git a/core/src/main/java/google/registry/env/common/default/WEB-INF/web.xml b/core/src/main/java/google/registry/env/common/default/WEB-INF/web.xml index 9d1967f0a..4eb1b3832 100644 --- a/core/src/main/java/google/registry/env/common/default/WEB-INF/web.xml +++ b/core/src/main/java/google/registry/env/common/default/WEB-INF/web.xml @@ -12,29 +12,6 @@ 1 - - - default - org.eclipse.jetty.servlet.DefaultServlet - - cacheControl - max-age=18000,public - - - precompressed - true - - - dirAllowed - false - - 1 - - - default - /console/* - - frontend-servlet