From 6922ee200fef0b06bd8f52b0e0a405ff55fa41b9 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jul 2024 20:46:47 +0200 Subject: [PATCH 01/40] Test --- rs/dre-canisters/frontendapp | 1 - rs/dre-canisters/hello | 1 + .../canister_ids.json | 3 + .../trustworthy-node-metrics/dfx.json | 10 + .../package-lock.json | 1989 +++++++++++++++++ .../trustworthy-node-metrics/package.json | 18 + .../trustworthy-node-metrics/pool_logs.sh | 2 +- .../index.html | 17 + .../package.json | 30 + .../public/.ic-assets.json5 | 56 + .../public/favicon.ico | Bin 0 -> 15406 bytes .../public/logo2.svg | 37 + .../src/App.jsx | 19 + .../src/components/NodeSelector.jsx | 43 + .../src/components/ReductionCalculator.jsx | 49 + .../src/index.scss | 37 + .../src/main.jsx | 10 + .../src/vite-env.d.ts | 1 + .../tsconfig.json | 21 + .../vite.config.js | 43 + .../src/trustworthy-node-metrics/src/lib.rs | 9 + .../src/stable_memory.rs | 7 + .../trustworthy-node-metrics.did | 1 + 23 files changed, 2402 insertions(+), 2 deletions(-) delete mode 160000 rs/dre-canisters/frontendapp create mode 160000 rs/dre-canisters/hello create mode 100644 rs/dre-canisters/trustworthy-node-metrics/package-lock.json create mode 100644 rs/dre-canisters/trustworthy-node-metrics/package.json create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/.ic-assets.json5 create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/favicon.ico create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/logo2.svg create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/main.jsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/vite-env.d.ts create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/tsconfig.json create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js diff --git a/rs/dre-canisters/frontendapp b/rs/dre-canisters/frontendapp deleted file mode 160000 index 7d266f7a8..000000000 --- a/rs/dre-canisters/frontendapp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7d266f7a869a2833b6e2226bbae23f650eb3d117 diff --git a/rs/dre-canisters/hello b/rs/dre-canisters/hello new file mode 160000 index 000000000..1a7463bd9 --- /dev/null +++ b/rs/dre-canisters/hello @@ -0,0 +1 @@ +Subproject commit 1a7463bd90d1428cf4b74b2c89a50813bf9ab533 diff --git a/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json b/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json index 801c55b3c..70db89e21 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json +++ b/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json @@ -1,5 +1,8 @@ { "trustworthy-node-metrics": { "ic": "oqi72-gaaaa-aaaam-ac2pq-cai" + }, + "trustworthy-node-metrics-frontend": { + "ic": "hucfy-dyaaa-aaaam-ac37a-cai" } } \ No newline at end of file diff --git a/rs/dre-canisters/trustworthy-node-metrics/dfx.json b/rs/dre-canisters/trustworthy-node-metrics/dfx.json index 0708a6cd0..8c0039831 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/dfx.json +++ b/rs/dre-canisters/trustworthy-node-metrics/dfx.json @@ -4,6 +4,16 @@ "candid": "src/trustworthy-node-metrics/trustworthy-node-metrics.did", "package": "trustworthy-node-metrics", "type": "rust" + }, + "trustworthy-node-metrics-frontend": { + "dependencies": [ + "trustworthy-node-metrics" + ], + "source": [ + "src/trustworthy-node-metrics-frontend/dist" + ], + "type": "assets", + "workspace": "trustworthy-node-metrics-frontend" } }, "defaults": { diff --git a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json new file mode 100644 index 000000000..274ee1ec1 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json @@ -0,0 +1,1989 @@ +{ + "name": "trustworthy-node-metrics", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "trustworthy-node-metrics", + "workspaces": [ + "src/trustworthy-node-metrics-frontend" + ], + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "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.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.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/@babel/generator": { + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", + "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", + "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", + "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dfinity/agent": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.7.tgz", + "integrity": "sha512-w34yvlUTpPBG8nLOD0t/ao3k2xonOFq4QGvfJ1HiS/nIggdza/3xC3nLBszGrjVYWj1jqu8BLFvQXCAeWin75A==", + "dependencies": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1", + "ts-node": "^10.8.2" + }, + "peerDependencies": { + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7" + } + }, + "node_modules/@dfinity/candid": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.7.tgz", + "integrity": "sha512-lTcjK/xrSyT7wvUQ2pApG+yklQAwxaofQ04D1IWv0/8gKbY0eUbh8G2w6+CypJ15Hb1CH24ijUj8nWdeX/z3jg==", + "dependencies": { + "ts-node": "^10.8.2" + } + }, + "node_modules/@dfinity/principal": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.7.tgz", + "integrity": "sha512-6/AkYzpGEH6Jw/0+B/EeeQn+5u2GDDvRLt1kQPhIG4txQYFnOy04H3VvyrymmfAj6/CXUgrOrux6OxgYSLYVJg==", + "dependencies": { + "js-sha256": "^0.9.0", + "ts-node": "^10.8.2" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "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.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "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/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "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", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/node": { + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", + "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.24.5", + "@babel/plugin-transform-react-jsx-self": "^7.24.5", + "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "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/borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "dependencies": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "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/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", + "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/iso-url": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", + "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha512-L3mEegEWHRekSHjc7+sc8eJhba9Clq1PZ8kMkzf8OxElhXc8O4TS5MwcVlj9aEbm5dr81N90WHC5nAz3UO971w==", + "dependencies": { + "delimit-stream": "0.1.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sass": { + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "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/simple-cbor": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", + "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trustworthy-node-metrics-frontend": { + "resolved": "src/trustworthy-node-metrics-frontend", + "link": true + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "peer": true + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/vite": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-environment": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vite-plugin-environment/-/vite-plugin-environment-1.1.3.tgz", + "integrity": "sha512-9LBhB0lx+2lXVBEWxFZC+WO7PKEyE/ykJ7EPWCq95NEcCpblxamTbs5Dm3DLBGzwODpJMEnzQywJU8fw6XGGGA==", + "dev": true, + "peerDependencies": { + "vite": ">= 2.7" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + }, + "src/trustworthy-node-metrics-frontend": { + "version": "0.0.0", + "dependencies": { + "@dfinity/agent": "^0.15.7", + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.2.14", + "@types/react-dom": "^18.2.6", + "@vitejs/plugin-react": "^4.0.1", + "dotenv": "^16.3.1", + "sass": "^1.63.6", + "typescript": "^5.1.3", + "vite": "^4.3.9", + "vite-plugin-environment": "^1.1.3" + } + } + } +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/package.json b/rs/dre-canisters/trustworthy-node-metrics/package.json new file mode 100644 index 000000000..02a36004c --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/package.json @@ -0,0 +1,18 @@ +{ + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + }, + "name": "trustworthy-node-metrics", + "scripts": { + "build": "npm run build --workspaces --if-present", + "prebuild": "npm run prebuild --workspaces --if-present", + "pretest": "npm run prebuild --workspaces --if-present", + "start": "npm start --workspaces --if-present", + "test": "npm test --workspaces --if-present" + }, + "type": "module", + "workspaces": [ + "src/trustworthy-node-metrics-frontend" + ] +} \ No newline at end of file diff --git a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh index cd448a976..904bbbeeb 100755 --- a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh +++ b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh @@ -3,7 +3,7 @@ # Function to fetch logs and filter out new lines fetch_and_filter_logs() { # Fetch logs - new_logs=$(dfx canister logs trustworthy-node-metrics --network staging) + new_logs=$(dfx canister logs trustworthy-node-metrics --network ic) # Compare with previous logs to find new ones while IFS= read -r line; do diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html new file mode 100644 index 000000000..a8f14f76b --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html @@ -0,0 +1,17 @@ + + + + + + + IC Hello Starter + + + + + +
+ + + + \ No newline at end of file diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json new file mode 100644 index 000000000..52bba0b35 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json @@ -0,0 +1,30 @@ +{ + "name": "trustworthy-node-metrics-frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "setup": "npm i && dfx canister create trustworthy-node-metrics && dfx generate trustworthy-node-metrics && dfx deploy", + "start": "vite --port 3000", + "prebuild": "dfx generate", + "build": "tsc && vite build", + "format": "prettier --write \"src/**/*.{json,js,jsx,ts,tsx,css,scss}\"" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "@dfinity/agent": "^0.15.7", + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7" + }, + "devDependencies": { + "@types/react": "^18.2.14", + "@types/react-dom": "^18.2.6", + "@vitejs/plugin-react": "^4.0.1", + "dotenv": "^16.3.1", + "sass": "^1.63.6", + "typescript": "^5.1.3", + "vite": "^4.3.9", + "vite-plugin-environment": "^1.1.3" + } +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/.ic-assets.json5 b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/.ic-assets.json5 new file mode 100644 index 000000000..394b81c66 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/.ic-assets.json5 @@ -0,0 +1,56 @@ +[ + { + "match": "**/*", + "headers": { + // Security: The Content Security Policy (CSP) given below aims at working with many apps rather than providing maximal security. + // We recommend tightening the CSP for your specific application. Some recommendations are as follows: + // - Use the CSP Evaluator (https://csp-evaluator.withgoogle.com/) to validate the CSP you define. + // - Follow the “Strict CSP” recommendations (https://csp.withgoogle.com/docs/strict-csp.html). However, note that in the context of the IC, + // nonces cannot be used because the response bodies must be static to work well with HTTP asset certification. + // Thus, we recommend to include script hashes (in combination with strict-dynamic) in the CSP as described + // in https://csp.withgoogle.com/docs/faq.html in section “What if my site is static and I can't add nonces to scripts?”. + // See for example the II CSP (https://github.com/dfinity/internet-identity/blob/main/src/internet_identity/src/http.rs). + // - It is recommended to tighten the connect-src directive. With the current CSP configuration the browser can + // make requests to https://*.icp0.io, hence being able to call any canister via https://icp0.io/api/v2/canister/{canister-ID}. + // This could potentially be used in combination with another vulnerability (e.g. XSS) to exfiltrate private data. + // The developer can configure this policy to only allow requests to their specific canisters, + // e.g: connect-src 'self' https://icp-api.io/api/v2/canister/{my-canister-ID}, where {my-canister-ID} has the following format: aaaaa-aaaaa-aaaaa-aaaaa-aaa + // - It is recommended to configure style-src, style-src-elem and font-src directives with the resources your canister is going to use + // instead of using the wild card (*) option. Normally this will include 'self' but also other third party styles or fonts resources (e.g: https://fonts.googleapis.com or other CDNs) + + // Notes about the CSP below: + // - script-src 'unsafe-eval' is currently required because agent-js uses a WebAssembly module for the validation of bls signatures. + // There is currently no other way to allow execution of WebAssembly modules with CSP. + // See: https://github.com/WebAssembly/content-security-policy/blob/main/proposals/CSP.md. + // - We added img-src data: because data: images are used often. + // - frame-ancestors: none mitigates clickjacking attacks. See https://owasp.org/www-community/attacks/Clickjacking. + "Content-Security-Policy": "default-src 'self';script-src 'self' 'unsafe-eval';connect-src 'self' http://localhost:* https://icp0.io https://*.icp0.io https://icp-api.io;img-src 'self' data:;style-src * 'unsafe-inline';style-src-elem * 'unsafe-inline';font-src *;object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;", + + // Security: The permissions policy disables all features for security reasons. If your site needs such permissions, activate them. + // To configure permissions go here https://www.permissionspolicy.com/ + "Permissions-Policy": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()", + + // Security: Mitigates clickjacking attacks. + // See: https://owasp.org/www-community/attacks/Clickjacking. + "X-Frame-Options": "DENY", + + // Security: Avoids forwarding referrer information to other origins. + // See: https://owasp.org/www-project-secure-headers/#referrer-policy. + "Referrer-Policy": "same-origin", + + // Security: Tells the user’s browser that it must always use HTTPS with your site. + // See: https://owasp.org/www-project-secure-headers/#http-strict-transport-security + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + + // Security: Prevents the browser from interpreting files as a different MIME type to what is specified in the Content-Type header. + // See: https://owasp.org/www-project-secure-headers/#x-content-type-options + "X-Content-Type-Options": "nosniff", + + // Security: Enables browser features to mitigate some of the XSS attacks. Note that it has to be in mode=block. + // See: https://owasp.org/www-community/attacks/xss/ + "X-XSS-Protection": "1; mode=block" + }, + // Uncomment to redirect all requests from .raw.icp0.io to .icp0.io + // "allow_raw_access": false + }, +] diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/favicon.ico b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..338fbf34cd80a1fd7d0c259aae42b566a56f7168 GIT binary patch literal 15406 zcmeHNd010d7Jq0v-KKTvSX)a%mY0o15!?W+v@>mOYwK8xl|}1Ht6=L^Aql}3f~e4< zqOGHKsah3YfCQmxXWH6tzSd4#ZSChqM+5?j8wn(AA%S=2+=LfH2yywQ|IFll-_3p7 zx#xGzz4zUd^ScBQKnx@X4V9!_Ui)Es^V%c(oR{Hk!ve4n~&og-RlnmZC zW<}8XPC566SF7FGw3i z2?|Uqe$mn8fyag>6DRKn`PFic$qqO^t)qjtfGn!lN(+of$j2sDpdr!vu8Jhx>E@ku z{!lfUGEGe?5XJidce(3G<2KIGEn3fD**aRHbUlC*XhRTF*2PRL>x|2myfIB9T7W2V zYA^YEt!y=x-LN)?A>%Cz-Q~v|unMAeSiUQcPL3S3?YWnY8qu6Da-=DbSMHKL3UV94 zS6KHpQ9|=}VS=SgILn+79Ebi8PNBgOo7&6A@3l2Y(P$`cx28z?;?EyOHvh0b%2rz# z(gt#NLy?q12!=d`1_?}5AX01AjB(7?Ns zx%D=p3CB8n>(1@ZXwawNo|~!Q8V)PCjhA7qZH96I*8jY;5hm{KT5zs6QVQ1gGY}Ir z!R&Z+xV&b`^*qaR~H z5QFGe4ZrpXivjx?Y%Ktt&bY#NYgM$6WMzBm z07_W!F zPL^mzo+DNx*CMqbe>r>KTb;(eG0};k5tXM%Uano(Cr#)xj8vqWI}Ts+g^Wlw9YETx}C-THT&K=+4NkEcoxbQ zEnu?9#VgqR-s<{dX)5UMW^Lb^tLTPU7C{`^PA0a#;7x|TH(|eRVN|gl^g|!$yIlT1 zk~%5ogVC=s+2S`Djd`N z8P{-Kda;0ffHxOCD2z8(I5A)x=5ArUWk*ob&8HmtAx;m?Xo($_(|#dhV+R_uqmvoG zxAO#!-`(+DEFlAH3xf?Ovc@9)!sk#?;#72G=}R{%cZXMkE|RuY|ncio#TFC_JYfjo#RCE#f1q=l93aRCS3g2!A`= z?esWrs)hd&_`e&g`&NwtgbC(U7>5>@FA^<`c)o>^rdUwOsx~Gpv;EXaja70>rtcZ< zXTb0}tRFh~Z&?TWo50?)P;0K03ZLjJ(fdwNQrlDDgSF5nX8}hOnPj;vUT7(oENxAU zOhzuB^_J@Y%Gvf~utGcWB+ zC&s1X{4!P%bWSS|sx~ONSDGMSY=u0nEuGtl>n3@S@i)wSzd!88UGu9q%OsCN{s(i; zI0u4r+Z|ABP^?gzAy0yHB>F2_X*ABA_`>S>O#bwjk3+6|O$P5@W@XSX2D0$yQzWx`Sv+uE?fl24yWO)N;-rkYBH?~5b{LL4a zQKRDxuGLC1AP;o|eA@>rzE`UaMd!8S(HU(Fs??5w>k#}N19ntgqNQPgw%@r&@%9W} zBiMH!Q&41A@%2c>Kjz>ZG8{Ji+@|1O_%WSRt(S8fPC-A|dUF1^Y;caP6L?{`&Qli$*MFgnKf0{+=&6~y3vDxWRcMy(0+Uku71~*%Mi;c>yMW6m zYd9$WlV{uPwVJ;*g%WPJXA1T@`3k1MrRPv8+$>4k^bbfmX0?!TTgGk_T%E1N; z%m;@J=^Uez)8QC@Rd8BDd)^PIE0c_XTx&%i+*)ZD_|*WpXLa>KzH^TWLIKf7kPx_y z%`rOr4ag}oIJf?qt{#0>yt@0Gc7mekJH^6w)Y<&(Ad1Yrq81ha-?1I=gAM$`3reAW zdVk-T)so6b(>bPhz=m39Utl|Mf&DC;#^ds*Z;ET^;3on1K`3}`y2cFPZmXlEd*HeE zygu+VQKi`~~1ga*IDUoi2_E=>;AxC{m?XlUYbD%yaNHV1tDc?3qvZ z!-=u-$&n}TR|YnY1N_xa8ytKZ?vHMjpyAt^!jXl*pLt-H;;|sd`)k;Cyw!0u8W^ST zN{H6kn^}G(R^Q6Vb;VoU-={_-KddHK{iG(9h$7X95^exHHl3iz0-x=>w~@v*hQRna z4ZiQjcB~QCp`**>E`PiEzS&SLdDmUm*E#IDc?j@->EtFbKVe6c^=)Tgr0X4faj>k0 zOcrK|Qfjh9D^V7yU?|)Vf^})W+Vy8OW1<$Ybp9JVcR;fJ{}v8=m3T4!^OyDahCu^REh2CxBXL@OP9mzvCc(N~+^o?-qq zgLgHyWWk4RmkvaDV#hq3qMqsge~pbrcO4T%9kGpe`XBf` zovjc4b;39@TM}2R5ho%i-v|9bzAJafcDr+o9oD6#fZgOa)=^dAD3rfW&5WAU06dtv zRxr!_3gP4*Zr7yic~r4&esrmwiN@bjCr^6Wef;D{#XYn>WcrU_1K>||@P!)D;_oSP z=^fACdRm$cF-tG(*pA)#%eqI;tq1N3bBSgK_?zFv31+;d^Nx;}j-Us|@9+E~s?dh8 z4L$SVEW4MEZKQbivzZ%0rvcX(2PF~s#sw|eqU2`&GL` zIpvF=smmKZ4S32odir7B#Vm5sOqQ?olrbC(4uQ3EJ78_azGe%oO_;+jz4#d!D41>H z0`_tkJHRD7cud?6V1xN8*s+o~w`s6vyN+v$8W54&IwfMW_4JsJt<2b+R^;GVi)_Y8 zdempXD3+<(7nb}_)p*;+aj&Aak{Mt_0+jhi;9Pg)z!>pTh&C0GT(0e|blAMfHrTjBm!{I^=3A(Bt_aDXU4wz4TGRMnn0 zO4D{dJhz>R*kolQKenQ=pIEym?CVq#5My|=`4TM{1l;7li~BJ?udN z424j-4Mj3kwJ#J^?iz*u{pm;qJhW?!xM6nOgYTvZWU}G^lWSe{w1FSrIvn=KegHN! zyZVA1Q;B9IddrL?i&}seZe@a3w4l&5;D&*p9+lnBgy&j6kIe6c_}RPf-E|obgbl&# zBw+0GJ?VoR#tdLT2W!&{^>pBE*VU1;uRTJ(X_*FlY^z+Hx`SVbxdFVk%Z5}73SJI2 zq_?+>%Xj7K^*f`#whjoLOxn@R~*@v@C|XybA0|5hXOeE?U?q zgS`}Yy;l3y2R(@QSpROvosW;-4T8U6zX$vt@O!}T0lx?Q9`Jj>?*YFD{)avAAIbp{ A0{{R3 literal 0 HcmV?d00001 diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/logo2.svg b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/logo2.svg new file mode 100644 index 000000000..74bc67e39 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/logo2.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx new file mode 100644 index 000000000..6493a1b78 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx @@ -0,0 +1,19 @@ +import React, { useState } from 'react'; +import NodeSelector from './components/NodeSelector'; +import ReductionCalculator from './components/ReductionCalculator'; + +function App() { + const [selectedNode, setSelectedNode] = useState(null); + + return ( +
+
+

Node Selector

+ + {selectedNode && } +
+
+ ); +} + +export default App; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx new file mode 100644 index 000000000..7f01ca8c5 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx @@ -0,0 +1,43 @@ +import React, { useState, useEffect } from 'react'; +import { Actor, HttpAgent } from '@dfinity/agent'; +import { trustworthy_node_metrics } from '../../../declarations/trustworthy-node-metrics'; // Adjust the path as needed + +const NodeSelector = ({ onSelectNode }) => { + const [nodes, setNodes] = useState([]); + const [selectedNode, setSelectedNode] = useState(''); + + useEffect(() => { + const fetchNodes = async () => { + try { + const fetchedNodes = await trustworthy_node_metrics.get_nodes(); + setNodes(fetchedNodes); + } catch (error) { + console.error("Error fetching nodes:", error); + } + }; + + fetchNodes(); + }, []); + + const handleChange = (event) => { + const nodeId = event.target.value; + setSelectedNode(nodeId); + onSelectNode(nodeId); + }; + + return ( +
+ + +
+ ); +}; + +export default NodeSelector; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx new file mode 100644 index 000000000..7e41e5826 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx @@ -0,0 +1,49 @@ +import React, { useState } from 'react'; +import { Actor, HttpAgent } from '@dfinity/agent'; +import { idlFactory } from '../../../declarations/trustworthy-node-metrics'; // Adjust the path as needed + +const ReductionCalculator = ({ selectedNode }) => { + const [rate, setRate] = useState(1.0); + const [consecutiveDays, setConsecutiveDays] = useState(false); + const [reduction, setReduction] = useState(null); + + const calculateReduction = async () => { + const agent = new HttpAgent({ host: 'http://localhost:8000' }); + const actor = Actor.createActor(idlFactory, { agent, canisterId: 'your-canister-id' }); // Replace 'your-canister-id' with actual ID + const penalty = { + consecutive_days: consecutiveDays, + rate: parseFloat(rate) + }; + const reductionValue = await actor.calculate_reduction_for_node(selectedNode, penalty); + setReduction(reductionValue); + }; + + return ( +
+
+ +
+
+ +
+ + {reduction !== null &&

Reduction: {reduction}

} +
+ ); +}; + +export default ReductionCalculator; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss new file mode 100644 index 000000000..c1c320834 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss @@ -0,0 +1,37 @@ +body { + font-family: sans-serif; + font-size: 1.5rem; +} + +img { + max-width: 50vw; + max-height: 25vw; + display: block; + margin: auto; +} + +form { + display: flex; + justify-content: center; + gap: 0.5em; + flex-flow: row wrap; + max-width: 40vw; + margin: auto; + align-items: baseline; +} + +button[type="submit"] { + padding: 5px 20px; + margin: 10px auto; + float: right; +} + +#greeting { + margin: 10px auto; + padding: 10px 60px; + border: 1px solid #222; +} + +#greeting:empty { + display: none; +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/main.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/main.jsx new file mode 100644 index 000000000..173e7221c --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/main.jsx @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; +import './index.scss'; + +ReactDOM.createRoot(document.getElementById('root')).render( + + + , +); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/vite-env.d.ts b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/tsconfig.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/tsconfig.json new file mode 100644 index 000000000..39a545e91 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "ESNext", + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "types": ["vite/client"] + }, + "include": ["src"] +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js new file mode 100644 index 000000000..670b0347b --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js @@ -0,0 +1,43 @@ +import { fileURLToPath, URL } from 'url'; +import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite'; +import environment from 'vite-plugin-environment'; +import dotenv from 'dotenv'; + +dotenv.config({ path: '../../.env' }); + +export default defineConfig({ + build: { + emptyOutDir: true, + }, + optimizeDeps: { + esbuildOptions: { + define: { + global: "globalThis", + }, + }, + }, + server: { + proxy: { + "/api": { + target: "http://127.0.0.1:4943", + changeOrigin: true, + }, + }, + }, + plugins: [ + react(), + environment("all", { prefix: "CANISTER_" }), + environment("all", { prefix: "DFX_" }), + ], + resolve: { + alias: [ + { + find: "declarations", + replacement: fileURLToPath( + new URL("../declarations", import.meta.url) + ), + }, + ], + }, +}); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index bf493da34..7f990d42d 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -58,3 +58,12 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { + let nodes = stable_memory::get_nodes(); + ic_cdk::println!("Fetched {} nodes for frontend", nodes.len()); + + nodes +} + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 40910cdd1..e3ab07288 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -19,3 +19,10 @@ pub fn latest_key() -> Option { pub fn get_metrics(ts: TimestampNanos) -> Vec<(TimestampNanos, Vec)> { MAP.with(|p| p.borrow().range(ts..).map(|(ts, storable)| (ts, storable.0)).collect_vec()) } + +pub fn get_nodes() -> Vec { + MAP.with(|p| p.borrow().iter().collect_vec()) + .into_iter().flat_map(|(_, storable)| { + storable.0.into_iter().map(|s| s.node_metrics.into_iter().map(|n| n.node_id.to_string()).collect_vec()) + }).flatten().collect_vec() +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index 5440edd0d..f5fdaa2e1 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -24,4 +24,5 @@ type SubnetNodeMetricsArgs = record { service : { "subnet_node_metrics" : (SubnetNodeMetricsArgs) -> (SubnetNodeMetricsResult) query; + "get_nodes" : () -> (vec text) query; } From fec1cfaa4b2a6e8f82d032ac643d9b0c13f302b4 Mon Sep 17 00:00:00 2001 From: Pietro Date: Thu, 25 Jul 2024 18:01:01 +0200 Subject: [PATCH 02/40] Functioning app --- rs/dre-canisters/hello | 1 - rs/dre-canisters/hello-test | 1 + .../package-lock.json | 1429 ++++++- .../trustworthy-node-metrics/package.json | 2 +- .../index.html | 1 + .../package-lock.json | 3274 +++++++++++++++++ .../package.json | 18 +- .../src/App.jsx | 19 - .../src/App.tsx | 165 + .../{public => src/assets}/.ic-assets.json5 | 0 .../{public => src/assets}/favicon.ico | Bin .../src/assets/icp_logo.svg | 28 + .../{public => src/assets}/logo2.svg | 0 .../src/components/ChartGrid.tsx | 130 + .../src/components/Drawer.tsx | 57 + .../src/components/FilterBar.tsx | 54 + .../src/components/Header.tsx | 25 + .../src/components/NodeSelector.jsx | 43 - .../src/components/ReductionCalculator.jsx | 49 - .../src/index.scss | 16 - .../src/models/NodeMetrics.tsx | 23 + .../vite.config.js | 2 +- 22 files changed, 5165 insertions(+), 172 deletions(-) delete mode 160000 rs/dre-canisters/hello create mode 160000 rs/dre-canisters/hello-test create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package-lock.json delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx rename rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/{public => src/assets}/.ic-assets.json5 (100%) rename rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/{public => src/assets}/favicon.ico (100%) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/icp_logo.svg rename rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/{public => src/assets}/logo2.svg (100%) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx diff --git a/rs/dre-canisters/hello b/rs/dre-canisters/hello deleted file mode 160000 index 1a7463bd9..000000000 --- a/rs/dre-canisters/hello +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1a7463bd90d1428cf4b74b2c89a50813bf9ab533 diff --git a/rs/dre-canisters/hello-test b/rs/dre-canisters/hello-test new file mode 160000 index 000000000..e1e9496a9 --- /dev/null +++ b/rs/dre-canisters/hello-test @@ -0,0 +1 @@ +Subproject commit e1e9496a940c88fc1e5935a03acb519ec609f6e1 diff --git a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json index 274ee1ec1..b7d3a857c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json +++ b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json @@ -30,7 +30,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -82,7 +81,6 @@ "version": "7.24.10", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", - "dev": true, "dependencies": { "@babel/types": "^7.24.9", "@jridgewell/gen-mapping": "^0.3.5", @@ -113,7 +111,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -125,7 +122,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, "dependencies": { "@babel/template": "^7.24.7", "@babel/types": "^7.24.7" @@ -138,7 +134,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -150,7 +145,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" @@ -204,7 +198,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, "dependencies": { "@babel/types": "^7.24.7" }, @@ -216,7 +209,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -225,7 +217,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -256,7 +247,6 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -271,7 +261,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -309,11 +298,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.24.7", @@ -327,7 +326,6 @@ "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.24.8", @@ -348,7 +346,6 @@ "version": "7.24.9", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", @@ -412,6 +409,155 @@ "ts-node": "^10.8.2" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", + "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/react": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", + "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", + "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.9.0", + "@emotion/utils": "^1.4.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -764,11 +910,44 @@ "node": ">=12" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "dependencies": { + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + }, "node_modules/@jridgewell/gen-mapping": { "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.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -790,7 +969,6 @@ "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" } @@ -804,12 +982,558 @@ "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", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", + "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.5.tgz", + "integrity": "sha512-bn88xxU/J9UV0s6+eutq7o3TTOrOlbCX+KshFb8kxgIxJZZfYz3JbAXVMivvoMF4Md6jCVUzM9HEkf4Ajab4tw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.172", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.172.tgz", + "integrity": "sha512-stpa3WTsDE1HamFR4eeS6Bhxalm+u9FhzzNph/PrDMdWSRBHlJs2mqvZ6FEoO22O7MOCwNMqbXTkvEwsyEf0ew==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/system": "^5.16.1", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.1", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": ">=5.15.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", + "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.4", + "@mui/system": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", + "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.4", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", + "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", + "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.4", + "@mui/styled-engine": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", + "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.11.0.tgz", + "integrity": "sha512-qNmrXk2eKoXOuxyLX6Vg4paWPcRttnIQx8hxuHc/avvGzX55kS4s69G8NIG0mtqygtDMcYJPDGNCJOlmkp1uAg==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@react-spring/rafz": "^9.7.3", + "@react-spring/web": "^9.7.3", + "clsx": "^2.1.1", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.11.0.tgz", + "integrity": "sha512-+zPWs1dwe7J1nZ2iFhTgCae31BLMYMQ2VtQfHxx21Dh6gbBRy/U7YJZg1LdhfQyE093S3e4A5uMZ6PUWdne7iA==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers-pro": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-7.11.0.tgz", + "integrity": "sha512-qCHsoNoFgldGxlJE77vL18lhbV7Qg15UFkqCQWV8KbUd5PLrK1kaIf2ddMwLGKJKl4sxSU6rgH/yat95HDdggA==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@mui/x-date-pickers": "7.11.0", + "@mui/x-license": "7.11.0", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-license": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.11.0.tgz", + "integrity": "sha512-4YOfiJ2CDque+nP4MNFU6eNiw2bf9rFGZtN9s0XRWXIaIoLKXICWcMx/PjYpqtLdSGG8eFe+EINX0oxiWC9XSg==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/utils": "^5.16.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", + "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", + "dependencies": { + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", + "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", + "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", + "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", + "dependencies": { + "@react-spring/rafz": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", + "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", + "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/core": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -871,6 +1595,60 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, "node_modules/@types/node": { "version": "20.14.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", @@ -880,17 +1658,20 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -905,6 +1686,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@vitejs/plugin-react": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", @@ -950,7 +1739,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -976,6 +1764,20 @@ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/base64-arraybuffer": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", @@ -1107,6 +1909,14 @@ "ieee754": "^1.1.13" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001643", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", @@ -1131,7 +1941,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1141,6 +1950,18 @@ "node": ">=4" } }, + "node_modules/chart.js": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "peer": true, + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -1165,11 +1986,18 @@ "fsevents": "~2.3.2" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -1177,8 +2005,7 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/commander": { "version": "2.20.3", @@ -1191,6 +2018,21 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -1199,14 +2041,148 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1219,6 +2195,19 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/delimit-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", @@ -1232,6 +2221,15 @@ "node": ">=0.3.1" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -1250,6 +2248,14 @@ "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", "dev": true }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", @@ -1300,11 +2306,23 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1317,6 +2335,11 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1331,6 +2354,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -1356,7 +2387,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -1365,11 +2395,34 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -1395,11 +2448,39 @@ "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", "dev": true }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1412,6 +2493,20 @@ "node": ">=8" } }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1464,7 +2559,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -1472,6 +2566,11 @@ "node": ">=4" } }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "node_modules/json-text-sequence": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", @@ -1492,6 +2591,16 @@ "node": ">=6" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -1520,8 +2629,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nanoid": { "version": "3.3.7", @@ -1556,11 +2664,59 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -1602,6 +2758,21 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -1613,6 +2784,15 @@ "node": ">=0.10.0" } }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -1625,6 +2805,11 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -1634,6 +2819,35 @@ "node": ">=0.10.0" } }, + "node_modules/react-smooth": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", + "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -1659,6 +2873,75 @@ "node": ">=8.10.0" } }, + "node_modules/recharts": { + "version": "2.12.7", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.7.tgz", + "integrity": "sha512-hlLJMhPQfv4/3NBSAyq3gzGg4h2v69RJh6KU7b3pXYNNAELs9kEoXOjbkxdXpALqKBoVmVptGfLpxdaVYqjmXQ==", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^16.10.2", + "react-smooth": "^4.0.0", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/rollup": { "version": "3.29.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", @@ -1733,6 +3016,14 @@ "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -1750,11 +3041,15 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -1762,11 +3057,26 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -1887,6 +3197,27 @@ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/vite": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", @@ -1957,6 +3288,14 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -1971,8 +3310,20 @@ "@dfinity/agent": "^0.15.7", "@dfinity/candid": "^0.15.7", "@dfinity/principal": "^0.15.7", + "@emotion/react": "^11.13.0", + "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^5.16.5", + "@mui/lab": "^5.0.0-alpha.172", + "@mui/material": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/x-charts": "^7.11.0", + "@mui/x-date-pickers": "^7.11.0", + "@mui/x-date-pickers-pro": "^7.11.0", + "date-fns": "^2.30.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-chartjs-2": "^5.2.0", + "react-dom": "^18.2.0", + "recharts": "^2.12.7" }, "devDependencies": { "@types/react": "^18.2.14", diff --git a/rs/dre-canisters/trustworthy-node-metrics/package.json b/rs/dre-canisters/trustworthy-node-metrics/package.json index 02a36004c..ee5750654 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/package.json +++ b/rs/dre-canisters/trustworthy-node-metrics/package.json @@ -15,4 +15,4 @@ "workspaces": [ "src/trustworthy-node-metrics-frontend" ] -} \ No newline at end of file +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html index a8f14f76b..867e95ea5 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html @@ -7,6 +7,7 @@ IC Hello Starter + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package-lock.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package-lock.json new file mode 100644 index 000000000..309cc2ece --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package-lock.json @@ -0,0 +1,3274 @@ +{ + "name": "trustworthy-node-metrics-frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "trustworthy-node-metrics-frontend", + "version": "0.0.0", + "dependencies": { + "@dfinity/agent": "^0.15.7", + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7", + "@emotion/react": "^11.13.0", + "@emotion/styled": "^11.13.0", + "@mui/lab": "^5.0.0-alpha.172", + "@mui/material": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/x-charts": "^7.11.0", + "@mui/x-date-pickers": "^7.11.0", + "@mui/x-date-pickers-pro": "^7.11.0", + "date-fns": "^2.30.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "recharts": "^2.12.7" + }, + "devDependencies": { + "@types/react": "^18.2.14", + "@types/react-dom": "^18.2.6", + "@vitejs/plugin-react": "^4.0.1", + "dotenv": "^16.3.1", + "sass": "^1.63.6", + "typescript": "^5.1.3", + "vite": "^4.3.9", + "vite-plugin-environment": "^1.1.3" + } + }, + "node_modules/@ampproject/remapping": { + "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.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.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/@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/@babel/generator": { + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", + "dependencies": { + "@babel/types": "^7.24.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", + "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", + "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", + "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dfinity/agent": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.7.tgz", + "integrity": "sha512-w34yvlUTpPBG8nLOD0t/ao3k2xonOFq4QGvfJ1HiS/nIggdza/3xC3nLBszGrjVYWj1jqu8BLFvQXCAeWin75A==", + "dependencies": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1", + "ts-node": "^10.8.2" + }, + "peerDependencies": { + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7" + } + }, + "node_modules/@dfinity/candid": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.7.tgz", + "integrity": "sha512-lTcjK/xrSyT7wvUQ2pApG+yklQAwxaofQ04D1IWv0/8gKbY0eUbh8G2w6+CypJ15Hb1CH24ijUj8nWdeX/z3jg==", + "dependencies": { + "ts-node": "^10.8.2" + } + }, + "node_modules/@dfinity/principal": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.7.tgz", + "integrity": "sha512-6/AkYzpGEH6Jw/0+B/EeeQn+5u2GDDvRLt1kQPhIG4txQYFnOy04H3VvyrymmfAj6/CXUgrOrux6OxgYSLYVJg==", + "dependencies": { + "js-sha256": "^0.9.0", + "ts-node": "^10.8.2" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", + "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/react": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", + "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", + "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.9.0", + "@emotion/utils": "^1.4.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "dependencies": { + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", + "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.172", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.172.tgz", + "integrity": "sha512-stpa3WTsDE1HamFR4eeS6Bhxalm+u9FhzzNph/PrDMdWSRBHlJs2mqvZ6FEoO22O7MOCwNMqbXTkvEwsyEf0ew==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/system": "^5.16.1", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.1", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": ">=5.15.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", + "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.4", + "@mui/system": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", + "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.4", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", + "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", + "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.4", + "@mui/styled-engine": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", + "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.11.0.tgz", + "integrity": "sha512-qNmrXk2eKoXOuxyLX6Vg4paWPcRttnIQx8hxuHc/avvGzX55kS4s69G8NIG0mtqygtDMcYJPDGNCJOlmkp1uAg==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@react-spring/rafz": "^9.7.3", + "@react-spring/web": "^9.7.3", + "clsx": "^2.1.1", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.11.0.tgz", + "integrity": "sha512-+zPWs1dwe7J1nZ2iFhTgCae31BLMYMQ2VtQfHxx21Dh6gbBRy/U7YJZg1LdhfQyE093S3e4A5uMZ6PUWdne7iA==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers-pro": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-7.11.0.tgz", + "integrity": "sha512-qCHsoNoFgldGxlJE77vL18lhbV7Qg15UFkqCQWV8KbUd5PLrK1kaIf2ddMwLGKJKl4sxSU6rgH/yat95HDdggA==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@mui/x-date-pickers": "7.11.0", + "@mui/x-license": "7.11.0", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-license": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.11.0.tgz", + "integrity": "sha512-4YOfiJ2CDque+nP4MNFU6eNiw2bf9rFGZtN9s0XRWXIaIoLKXICWcMx/PjYpqtLdSGG8eFe+EINX0oxiWC9XSg==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/utils": "^5.16.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", + "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", + "dependencies": { + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", + "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", + "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", + "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", + "dependencies": { + "@react-spring/rafz": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", + "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", + "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/core": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/node": { + "version": "20.14.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz", + "integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==", + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", + "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.24.5", + "@babel/plugin-transform-react-jsx-self": "^7.24.5", + "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "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/borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "dependencies": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", + "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/iso-url": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-0.4.7.tgz", + "integrity": "sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog==", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha512-L3mEegEWHRekSHjc7+sc8eJhba9Clq1PZ8kMkzf8OxElhXc8O4TS5MwcVlj9aEbm5dr81N90WHC5nAz3UO971w==", + "dependencies": { + "delimit-stream": "0.1.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-smooth": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", + "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recharts": { + "version": "2.12.7", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.7.tgz", + "integrity": "sha512-hlLJMhPQfv4/3NBSAyq3gzGg4h2v69RJh6KU7b3pXYNNAELs9kEoXOjbkxdXpALqKBoVmVptGfLpxdaVYqjmXQ==", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^16.10.2", + "react-smooth": "^4.0.0", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sass": { + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "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/simple-cbor": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", + "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "peer": true + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vite": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-environment": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vite-plugin-environment/-/vite-plugin-environment-1.1.3.tgz", + "integrity": "sha512-9LBhB0lx+2lXVBEWxFZC+WO7PKEyE/ykJ7EPWCq95NEcCpblxamTbs5Dm3DLBGzwODpJMEnzQywJU8fw6XGGGA==", + "dev": true, + "peerDependencies": { + "vite": ">= 2.7" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json index 52bba0b35..59117d7b0 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json @@ -11,11 +11,23 @@ "format": "prettier --write \"src/**/*.{json,js,jsx,ts,tsx,css,scss}\"" }, "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0", "@dfinity/agent": "^0.15.7", "@dfinity/candid": "^0.15.7", - "@dfinity/principal": "^0.15.7" + "@dfinity/principal": "^0.15.7", + "@emotion/react": "^11.13.0", + "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^5.16.5", + "@mui/lab": "^5.0.0-alpha.172", + "@mui/material": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/x-charts": "^7.11.0", + "@mui/x-date-pickers": "^7.11.0", + "@mui/x-date-pickers-pro": "^7.11.0", + "date-fns": "^2.30.0", + "react": "^18.2.0", + "react-chartjs-2": "^5.2.0", + "react-dom": "^18.2.0", + "recharts": "^2.12.7" }, "devDependencies": { "@types/react": "^18.2.14", diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx deleted file mode 100644 index 6493a1b78..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { useState } from 'react'; -import NodeSelector from './components/NodeSelector'; -import ReductionCalculator from './components/ReductionCalculator'; - -function App() { - const [selectedNode, setSelectedNode] = useState(null); - - return ( -
-
-

Node Selector

- - {selectedNode && } -
-
- ); -} - -export default App; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx new file mode 100644 index 000000000..0e3b20776 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -0,0 +1,165 @@ +import React, { useState } from 'react'; +import FilterBar, { Filters } from './components/FilterBar.js'; +import { Box, CircularProgress, Drawer, List, ListItem, Menu, MenuItem, CssBaseline, ThemeProvider, createTheme, Typography, Toolbar, IconButton } from '@mui/material'; +import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; // Adjust the path as needed +import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; +import { NodeMetrics } from './models/NodeMetrics.js'; +import ChartGrid from './components/ChartGrid.js'; +import Header from './components/Header.js'; +import Logo from './assets/icp_logo.svg'; // Import SVG as React component + +const darkTheme = createTheme({ + palette: { + mode: 'dark', + divider: '#121212', + }, +}); + +function App() { + const [filters, setFilters] = useState({ + dateStart: new Date(), + dateEnd: new Date(), + subnet: '' + }); + const [data, setData] = useState([]); + const [filteredData, setFilteredData] = useState([]); + const [subnets, setSubnets] = useState>(new Set()); + const [error, setError] = useState(""); + const [drawerOpen, setDrawerOpen] = useState(false); // Add this state + const [menuAnchorEl, setMenuAnchorEl] = useState(null); // Menu anchor state + const drawerWidth = 120; + + React.useEffect(() => { + const fetchNodes = async () => { + try { + const request: SubnetNodeMetricsArgs = { + ts: [], + subnet_id: [], + }; + const response: SubnetNodeMetricsResult = await trustworthy_node_metrics.subnet_node_metrics(request); + + console.info("Got response", response); + + if ('Ok' in response) { + const metrics: NodeMetrics[] = response.Ok.flatMap((metricResponse) => { + return metricResponse.node_metrics.map((nodeMetrics) => { + return new NodeMetrics( + metricResponse.ts, + nodeMetrics.num_block_failures_total, + nodeMetrics.node_id, + nodeMetrics.num_blocks_proposed_total, + metricResponse.subnet_id + ); + }) + }); + const subnets: Set = new Set(metrics.map(metric => metric.subnet_id.toText())); + + setData(metrics); + setSubnets(subnets); + } else { + setError(response.Err); + } + } catch (error) { + console.error("Error fetching nodes:", error); + } + }; + + fetchNodes(); + }, []); + + React.useEffect(() => { + const filterData = () => { + const f = data.filter((metrics) => { + const metricsDate = metrics.date; + const isDateInRange = metricsDate >= filters.dateStart && metricsDate <= filters.dateEnd; + + return metrics.subnet_id.toText() === filters.subnet && isDateInRange; + }); + + setFilteredData(f); + } + + filterData(); + }, [filters, data]); + + const handleMenuOpen = (event: React.MouseEvent) => { + setMenuAnchorEl(event.currentTarget); + }; + + const handleMenuClose = () => { + setMenuAnchorEl(null); + }; + + const handleSubnetSelect = (subnet: string) => { + setFilters((prev) => ({ ...prev, subnet })); + handleMenuClose(); + }; + + if (error) { + return
Error: {error}
; + } + + if (data.length === 0) { + return ; + } + + return ( + + + + setDrawerOpen(false)} + sx={{ width: drawerWidth, flexShrink: 0 }} + PaperProps={{ + sx: { + width: drawerWidth, + bgcolor: 'palette.background.paper', + } + }} + > + + + + Logo + + + + + + + Subnets + + + + +
+ + + + + + + + handleSubnetSelect('')}> + None + + {Array.from(subnets).map((subnet, index) => ( + handleSubnetSelect(subnet)}> + {subnet} + + ))} + + + ); +} + +export default App; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/.ic-assets.json5 b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/.ic-assets.json5 similarity index 100% rename from rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/.ic-assets.json5 rename to rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/.ic-assets.json5 diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/favicon.ico b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/favicon.ico similarity index 100% rename from rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/favicon.ico rename to rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/favicon.ico diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/icp_logo.svg b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/icp_logo.svg new file mode 100644 index 000000000..6a1bf6c86 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/icp_logo.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/logo2.svg b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/logo2.svg similarity index 100% rename from rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/public/logo2.svg rename to rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/assets/logo2.svg diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx new file mode 100644 index 000000000..63e364dcf --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx @@ -0,0 +1,130 @@ +import React from 'react'; +import { Box, Grid, Paper, Stack, Typography } from '@mui/material'; +import { BarChart } from '@mui/x-charts'; +import { NodeMetrics } from '../models/NodeMetrics'; +import { styled } from '@mui/material/styles'; +import Divider from '@mui/material/Divider'; + +const Root = styled('div')(({ theme }) => ({ + width: '100%', + ...theme.typography.body2, + color: theme.palette.text.secondary, + '& > :not(style) ~ :not(style)': { + marginTop: theme.spacing(2), + }, + })); + + +interface ChartGridProps { + data: NodeMetrics[]; +} + +function groupBy(items: T[], key: K): Record { + return items.reduce((result, item) => { + const groupKey = String(item[key]); + if (!result[groupKey]) { + result[groupKey] = []; + } + result[groupKey].push(item); + return result; + }, {} as Record); +} + +const calculateDailyValues = (items: NodeMetrics[]) => { + const dailyValues = []; + let previousTotals = { num_block_failures_total: 0.0, num_blocks_proposed_total: 0.0 }; + + items.sort((a, b) => a.date.getTime() - b.date.getTime()); + + for (const item of items) { + const currentDate = item.date.toDateString(); + const currentTotals = { + num_block_failures_total: Number(item.num_block_failures_total), + num_blocks_proposed_total: Number(item.num_blocks_proposed_total), + }; + + if (previousTotals.num_block_failures_total || previousTotals.num_blocks_proposed_total) { + const dailyFailures = currentTotals.num_block_failures_total - previousTotals.num_block_failures_total; + const dailyProposed = currentTotals.num_blocks_proposed_total - previousTotals.num_blocks_proposed_total; + + dailyValues.push({ + date: currentDate, + num_block_failures_day: currentTotals.num_block_failures_total - previousTotals.num_block_failures_total, + num_blocks_proposed_day: currentTotals.num_blocks_proposed_total - previousTotals.num_blocks_proposed_total, + failureRate: dailyFailures / (dailyProposed + dailyFailures) * 100, + }); + } + + previousTotals = currentTotals; + } + + return dailyValues; +}; + + +const computeAverageFailureRate = (data: number[]): number => { + if (data.length === 0) return 0; + const sum = data.reduce((acc, val) => acc + val, 0); + return sum / data.length; + }; + +const ChartGrid: React.FC = ({ data }) => { + const groupedItems = groupBy(data, 'node_id'); + + const chartData = Object.keys(groupedItems).map(nodeId => { + const items = groupedItems[nodeId]; + const dailyData = calculateDailyValues(items); + + return { + nodeId, + title: nodeId.split('-')[0], + subnetId: items[0].subnet_id, + dailyData: dailyData, + failureRateSum: dailyData.reduce((sum, item) => sum + item.failureRate, 0), + failureRateAvg: computeAverageFailureRate(dailyData.map((elem) => elem.failureRate)), + }; + }).sort((a, b) => b.failureRateSum - a.failureRateSum); + + return ( + + {chartData.map(({ nodeId, title, subnetId, dailyData, failureRateAvg }, index) => ( + + + + + + + {nodeId} + + + + + + + + { + const formatted = new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }).replace(" ", "\n") + return formatted + }}]} + series={[ + { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, + ]} + dataset={dailyData} + height={400} + /> + + + + + + + ))} + + + ); +}; + +export default ChartGrid; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx new file mode 100644 index 000000000..9c2239c43 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx @@ -0,0 +1,57 @@ +import React, { useState } from 'react'; +import { Drawer, List, ListItem, Menu, MenuItem, Typography } from '@mui/material'; + +const SidebarDrawer = ({ drawerWidth, filters, setFilters, subnets }) => { + const [menuAnchorEl, setMenuAnchorEl] = useState(null); // Menu anchor state + + const handleMenuOpen = (event: React.MouseEvent) => { + setMenuAnchorEl(event.currentTarget); + }; + + const handleMenuClose = () => { + setMenuAnchorEl(null); + }; + + const handleSubnetSelect = (subnet: string) => { + setFilters((prev) => ({ ...prev, subnet })); + handleMenuClose(); + }; + + return ( + <> + + + + Subnet + + + + + handleSubnetSelect('')}> + None + + {Array.from(subnets).map((subnet, index) => ( + handleSubnetSelect(subnet)}> + {subnet} + + ))} + + + ); +}; + +export default SidebarDrawer; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx new file mode 100644 index 000000000..55c5f8f97 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx @@ -0,0 +1,54 @@ +import React, { useState, useEffect, ChangeEvent } from 'react'; +import { AppBar, Toolbar, TextField, Box, MenuItem, Select, InputLabel, FormControl, SelectChangeEvent } from '@mui/material'; +import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers'; +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; +import { Principal } from '@dfinity/principal'; +import ArrowRightIcon from '@mui/icons-material/ArrowRight'; + +// Define the types for props +export interface Filters { + dateStart: Date; + dateEnd: Date; + subnet: string; // Use string instead of String +} + +interface FilterBarProps { + filters: Filters; + setFilters: React.Dispatch>; + subnets: Set | null; // Use string instead of String +} + +const FilterBar: React.FC = ({ filters, setFilters }) => { + const handleDateStartChange = (newValue: Date | null) => { + if (newValue !== null) { + setFilters((prev) => ({ ...prev, dateStart: newValue })); + } + }; + + const handleDateEndChange = (newValue: Date | null) => { + if (newValue !== null) { + setFilters((prev) => ({ ...prev, dateEnd: newValue })); + } + }; + + return ( + + + + + + + + ); +}; + + +export default FilterBar; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx new file mode 100644 index 000000000..37c43a553 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx @@ -0,0 +1,25 @@ +import { AppBar, Toolbar, Typography, IconButton, styled } from '@mui/material'; +import Logo from '../assets/icp_logo.svg'; // Import SVG as React component + +const Title = styled(Typography)(({ theme }) => ({ + flexGrow: 1, + fontWeight: 500, + fontSize: '1.5rem', + letterSpacing: '1px', + fontFamily: 'Roboto, sans-serif', + color: 'white' + })); + + +const Header = () => { + return ( + + + + Nodes Penalties + + + ); +}; + +export default Header; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx deleted file mode 100644 index 7f01ca8c5..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeSelector.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Actor, HttpAgent } from '@dfinity/agent'; -import { trustworthy_node_metrics } from '../../../declarations/trustworthy-node-metrics'; // Adjust the path as needed - -const NodeSelector = ({ onSelectNode }) => { - const [nodes, setNodes] = useState([]); - const [selectedNode, setSelectedNode] = useState(''); - - useEffect(() => { - const fetchNodes = async () => { - try { - const fetchedNodes = await trustworthy_node_metrics.get_nodes(); - setNodes(fetchedNodes); - } catch (error) { - console.error("Error fetching nodes:", error); - } - }; - - fetchNodes(); - }, []); - - const handleChange = (event) => { - const nodeId = event.target.value; - setSelectedNode(nodeId); - onSelectNode(nodeId); - }; - - return ( -
- - -
- ); -}; - -export default NodeSelector; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx deleted file mode 100644 index 7e41e5826..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ReductionCalculator.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useState } from 'react'; -import { Actor, HttpAgent } from '@dfinity/agent'; -import { idlFactory } from '../../../declarations/trustworthy-node-metrics'; // Adjust the path as needed - -const ReductionCalculator = ({ selectedNode }) => { - const [rate, setRate] = useState(1.0); - const [consecutiveDays, setConsecutiveDays] = useState(false); - const [reduction, setReduction] = useState(null); - - const calculateReduction = async () => { - const agent = new HttpAgent({ host: 'http://localhost:8000' }); - const actor = Actor.createActor(idlFactory, { agent, canisterId: 'your-canister-id' }); // Replace 'your-canister-id' with actual ID - const penalty = { - consecutive_days: consecutiveDays, - rate: parseFloat(rate) - }; - const reductionValue = await actor.calculate_reduction_for_node(selectedNode, penalty); - setReduction(reductionValue); - }; - - return ( -
-
- -
-
- -
- - {reduction !== null &&

Reduction: {reduction}

} -
- ); -}; - -export default ReductionCalculator; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss index c1c320834..cc9943de1 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss @@ -19,19 +19,3 @@ form { margin: auto; align-items: baseline; } - -button[type="submit"] { - padding: 5px 20px; - margin: 10px auto; - float: right; -} - -#greeting { - margin: 10px auto; - padding: 10px 60px; - border: 1px solid #222; -} - -#greeting:empty { - display: none; -} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx new file mode 100644 index 000000000..2798390c4 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -0,0 +1,23 @@ +import { Principal } from '@dfinity/principal'; + +export class NodeMetrics { + date: Date; + num_block_failures_total: bigint; + node_id: Principal; + num_blocks_proposed_total: bigint; + subnet_id: Principal; + + constructor( + ts: bigint, + num_block_failures_total: bigint, + node_id: Principal, + num_blocks_proposed_total: bigint, + subnet_id: Principal + ) { + this.date = new Date(Number(ts / BigInt(1e6))); + this.num_block_failures_total = num_block_failures_total; + this.node_id = node_id; + this.num_blocks_proposed_total = num_blocks_proposed_total; + this.subnet_id = subnet_id; + } +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js index 670b0347b..11ec09040 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/vite.config.js @@ -20,7 +20,7 @@ export default defineConfig({ server: { proxy: { "/api": { - target: "http://127.0.0.1:4943", + target: "https://icp0.io", changeOrigin: true, }, }, From 25909b2c9b75506c04e2d980315bbb608c046999 Mon Sep 17 00:00:00 2001 From: Pietro Date: Thu, 25 Jul 2024 18:19:53 +0200 Subject: [PATCH 03/40] Move drawer in different component --- rs/dre-canisters/hello-test | 1 - .../src/App.tsx | 77 ++++--------------- .../src/components/Drawer.tsx | 62 ++++++++++----- .../src/components/Header.tsx | 1 - 4 files changed, 60 insertions(+), 81 deletions(-) delete mode 160000 rs/dre-canisters/hello-test diff --git a/rs/dre-canisters/hello-test b/rs/dre-canisters/hello-test deleted file mode 160000 index e1e9496a9..000000000 --- a/rs/dre-canisters/hello-test +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e1e9496a940c88fc1e5935a03acb519ec609f6e1 diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index 0e3b20776..2948f7b76 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -1,12 +1,12 @@ -import React, { useState } from 'react'; -import FilterBar, { Filters } from './components/FilterBar.js'; -import { Box, CircularProgress, Drawer, List, ListItem, Menu, MenuItem, CssBaseline, ThemeProvider, createTheme, Typography, Toolbar, IconButton } from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; +import FilterBar, { Filters } from './components/FilterBar'; +import Drawer from './components/Drawer'; // Import the updated Drawer component import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; // Adjust the path as needed import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; -import { NodeMetrics } from './models/NodeMetrics.js'; -import ChartGrid from './components/ChartGrid.js'; -import Header from './components/Header.js'; -import Logo from './assets/icp_logo.svg'; // Import SVG as React component +import { NodeMetrics } from './models/NodeMetrics'; +import ChartGrid from './components/ChartGrid'; +import Header from './components/Header'; const darkTheme = createTheme({ palette: { @@ -18,18 +18,16 @@ const darkTheme = createTheme({ function App() { const [filters, setFilters] = useState({ dateStart: new Date(), - dateEnd: new Date(), + dateEnd: new Date(), subnet: '' }); const [data, setData] = useState([]); const [filteredData, setFilteredData] = useState([]); const [subnets, setSubnets] = useState>(new Set()); const [error, setError] = useState(""); - const [drawerOpen, setDrawerOpen] = useState(false); // Add this state - const [menuAnchorEl, setMenuAnchorEl] = useState(null); // Menu anchor state const drawerWidth = 120; - React.useEffect(() => { + useEffect(() => { const fetchNodes = async () => { try { const request: SubnetNodeMetricsArgs = { @@ -67,7 +65,7 @@ function App() { fetchNodes(); }, []); - React.useEffect(() => { + useEffect(() => { const filterData = () => { const f = data.filter((metrics) => { const metricsDate = metrics.date; @@ -82,17 +80,8 @@ function App() { filterData(); }, [filters, data]); - const handleMenuOpen = (event: React.MouseEvent) => { - setMenuAnchorEl(event.currentTarget); - }; - - const handleMenuClose = () => { - setMenuAnchorEl(null); - }; - const handleSubnetSelect = (subnet: string) => { setFilters((prev) => ({ ...prev, subnet })); - handleMenuClose(); }; if (error) { @@ -108,34 +97,14 @@ function App() { setDrawerOpen(false)} - sx={{ width: drawerWidth, flexShrink: 0 }} - PaperProps={{ - sx: { - width: drawerWidth, - bgcolor: 'palette.background.paper', - } - }} - > - - - - Logo - - - - - - - Subnets - - - + subnets={subnets} + drawerWidth={drawerWidth} + theme={darkTheme} + onSubnetSelect={handleSubnetSelect} + />
@@ -144,20 +113,6 @@ function App() { - - handleSubnetSelect('')}> - None - - {Array.from(subnets).map((subnet, index) => ( - handleSubnetSelect(subnet)}> - {subnet} - - ))} - ); } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx index 9c2239c43..5d5595987 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx @@ -1,8 +1,28 @@ +// src/components/Drawer.tsx + import React, { useState } from 'react'; -import { Drawer, List, ListItem, Menu, MenuItem, Typography } from '@mui/material'; +import { Drawer as MUIDrawer, List, ListItem, Typography, Menu, MenuItem, Box, Theme, IconButton, Toolbar } from '@mui/material'; +import { SxProps } from '@mui/system'; +import Logo from '../assets/icp_logo.svg'; // Import SVG as React component + +interface DrawerProps { + subnets: Set; + drawerWidth: number; + theme: Theme; + onSubnetSelect: (subnet: string) => void; +} + +const Drawer: React.FC = ({ subnets, drawerWidth, theme, onSubnetSelect }) => { + const [drawerOpen, setDrawerOpen] = useState(false); + const [menuAnchorEl, setMenuAnchorEl] = useState(null); -const SidebarDrawer = ({ drawerWidth, filters, setFilters, subnets }) => { - const [menuAnchorEl, setMenuAnchorEl] = useState(null); // Menu anchor state + const handleDrawerOpen = () => { + setDrawerOpen(true); + }; + + const handleDrawerClose = () => { + setDrawerOpen(false); + }; const handleMenuOpen = (event: React.MouseEvent) => { setMenuAnchorEl(event.currentTarget); @@ -13,29 +33,35 @@ const SidebarDrawer = ({ drawerWidth, filters, setFilters, subnets }) => { }; const handleSubnetSelect = (subnet: string) => { - setFilters((prev) => ({ ...prev, subnet })); + onSubnetSelect(subnet); handleMenuClose(); }; return ( <> - - - Subnet - - - + + + Logo + + + + + + + Subnets + + + { ); }; -export default SidebarDrawer; +export default Drawer; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx index 37c43a553..ef250fa9c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx @@ -1,5 +1,4 @@ import { AppBar, Toolbar, Typography, IconButton, styled } from '@mui/material'; -import Logo from '../assets/icp_logo.svg'; // Import SVG as React component const Title = styled(Typography)(({ theme }) => ({ flexGrow: 1, From 7806ad56f74ba13e545f2086553982a6128492ef Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 29 Jul 2024 20:27:23 +0200 Subject: [PATCH 04/40] Move on with the app --- .../package-lock.json | 361 +++++++++++++++++- .../package.json | 2 + .../src/App.tsx | 80 ++-- .../src/components/ChartComponent.tsx | 20 + .../src/components/ChartGrid.tsx | 238 ++++++++---- .../src/components/Drawer.tsx | 169 ++++---- .../src/components/FilterBar.tsx | 3 +- 7 files changed, 693 insertions(+), 180 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx diff --git a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json index b7d3a857c..be9fd1d3c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json +++ b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json @@ -1459,6 +1459,146 @@ "react": "^17.0.0 || ^18.0.0" } }, + "node_modules/@next/env": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz", + "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz", + "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -1534,6 +1674,28 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@remix-run/router": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", + "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -1750,7 +1912,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, + "devOptional": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1817,7 +1979,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" }, @@ -1846,7 +2008,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "devOptional": true, "dependencies": { "fill-range": "^7.1.1" }, @@ -1909,6 +2071,17 @@ "ieee754": "^1.1.13" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1921,7 +2094,6 @@ "version": "1.0.30001643", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -1966,7 +2138,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, + "devOptional": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1986,6 +2158,11 @@ "fsevents": "~2.3.2" } }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -2327,7 +2504,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "devOptional": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2375,7 +2552,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "devOptional": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -2391,6 +2568,11 @@ "node": ">=4" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2446,7 +2628,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "dev": true + "devOptional": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -2485,7 +2667,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, + "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -2511,7 +2693,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -2520,7 +2702,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -2532,7 +2714,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.12.0" } @@ -2635,7 +2817,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -2649,6 +2830,82 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/next": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz", + "integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==", + "dependencies": { + "@next/env": "14.2.5", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.5", + "@next/swc-darwin-x64": "14.2.5", + "@next/swc-linux-arm64-gnu": "14.2.5", + "@next/swc-linux-arm64-musl": "14.2.5", + "@next/swc-linux-x64-gnu": "14.2.5", + "@next/swc-linux-x64-musl": "14.2.5", + "@next/swc-win32-arm64-msvc": "14.2.5", + "@next/swc-win32-ia32-msvc": "14.2.5", + "@next/swc-win32-x64-msvc": "14.2.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -2659,7 +2916,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -2722,7 +2979,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8.6" }, @@ -2819,6 +3076,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz", + "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", + "dependencies": { + "@remix-run/router": "1.18.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", + "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", + "dependencies": { + "@remix-run/router": "1.18.0", + "react-router": "6.25.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-smooth": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", @@ -2865,7 +3152,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, + "devOptional": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -2981,7 +3268,7 @@ "version": "1.77.8", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", - "dev": true, + "devOptional": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -3028,11 +3315,18 @@ "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" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -3041,6 +3335,28 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", @@ -3085,7 +3401,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "dependencies": { "is-number": "^7.0.0" }, @@ -3139,6 +3455,11 @@ } } }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/typescript": { "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", @@ -3320,9 +3641,11 @@ "@mui/x-date-pickers": "^7.11.0", "@mui/x-date-pickers-pro": "^7.11.0", "date-fns": "^2.30.0", + "next": "^14.2.5", "react": "^18.2.0", "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.25.1", "recharts": "^2.12.7" }, "devDependencies": { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json index 59117d7b0..a47ee681d 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json @@ -24,9 +24,11 @@ "@mui/x-date-pickers": "^7.11.0", "@mui/x-date-pickers-pro": "^7.11.0", "date-fns": "^2.30.0", + "next": "^14.2.5", "react": "^18.2.0", "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.25.1", "recharts": "^2.12.7" }, "devDependencies": { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index 2948f7b76..1d8e21de3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -1,11 +1,13 @@ import React, { useState, useEffect } from 'react'; import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; import FilterBar, { Filters } from './components/FilterBar'; -import Drawer from './components/Drawer'; // Import the updated Drawer component +import Drawer from './components/Drawer'; +import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; // Adjust the path as needed import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; import { NodeMetrics } from './models/NodeMetrics'; -import ChartGrid from './components/ChartGrid'; +import { ChartGrid } from './components/ChartGrid'; +import { StackedChart } from './components/ChartGrid'; import Header from './components/Header'; const darkTheme = createTheme({ @@ -16,16 +18,22 @@ const darkTheme = createTheme({ }); function App() { + const thirtyDaysAgo = new Date(); + thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); + const [filters, setFilters] = useState({ - dateStart: new Date(), + dateStart: thirtyDaysAgo, dateEnd: new Date(), - subnet: '' + subnet: null, + nodeProvider: null }); const [data, setData] = useState([]); const [filteredData, setFilteredData] = useState([]); const [subnets, setSubnets] = useState>(new Set()); + const [nodeProviders, setNodeProviders] = useState>(new Set()); + const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(""); - const drawerWidth = 120; + const drawerWidth = 180; useEffect(() => { const fetchNodes = async () => { @@ -54,6 +62,7 @@ function App() { setData(metrics); setSubnets(subnets); + setIsLoading(false); } else { setError(response.Err); } @@ -61,7 +70,7 @@ function App() { console.error("Error fetching nodes:", error); } }; - + fetchNodes(); }, []); @@ -71,48 +80,59 @@ function App() { const metricsDate = metrics.date; const isDateInRange = metricsDate >= filters.dateStart && metricsDate <= filters.dateEnd; - return metrics.subnet_id.toText() === filters.subnet && isDateInRange; + if (filters.subnet !== null) { + return metrics.subnet_id.toText() === filters.subnet && isDateInRange; + } + + return isDateInRange; }); setFilteredData(f); } - filterData(); }, [filters, data]); - const handleSubnetSelect = (subnet: string) => { - setFilters((prev) => ({ ...prev, subnet })); - }; - if (error) { return
Error: {error}
; } - if (data.length === 0) { - return ; + if (isLoading) { + return } return ( - - - -
- - + + + + +
+ + + + + } /> + } /> + } /> + } /> + - - + ); } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx new file mode 100644 index 000000000..83b8b3413 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Line } from 'react-chartjs-2'; +import { Box } from '@mui/material'; +import { NodeMetrics } from '../models/NodeMetrics'; + + +interface ChartProps { + data: NodeMetrics[]; + name: string | null; + } + + +const ChartComponent: React.FC = ({ data }) => { + return ( + + + ); +}; + +export default ChartComponent; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx index 63e364dcf..0811fe859 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx @@ -1,6 +1,6 @@ -import React from 'react'; -import { Box, Grid, Paper, Stack, Typography } from '@mui/material'; -import { BarChart } from '@mui/x-charts'; +import React, { useState } from 'react'; +import { Box, CircularProgress, Grid, Paper, Stack, Typography } from '@mui/material'; +import { axisClasses, BarChart, StackOrderType } from '@mui/x-charts'; import { NodeMetrics } from '../models/NodeMetrics'; import { styled } from '@mui/material/styles'; import Divider from '@mui/material/Divider'; @@ -14,11 +14,6 @@ const Root = styled('div')(({ theme }) => ({ }, })); - -interface ChartGridProps { - data: NodeMetrics[]; -} - function groupBy(items: T[], key: K): Record { return items.reduce((result, item) => { const groupKey = String(item[key]); @@ -37,7 +32,7 @@ const calculateDailyValues = (items: NodeMetrics[]) => { items.sort((a, b) => a.date.getTime() - b.date.getTime()); for (const item of items) { - const currentDate = item.date.toDateString(); + const currentDate = item.date; const currentTotals = { num_block_failures_total: Number(item.num_block_failures_total), num_blocks_proposed_total: Number(item.num_blocks_proposed_total), @@ -68,63 +63,176 @@ const computeAverageFailureRate = (data: number[]): number => { return sum / data.length; }; -const ChartGrid: React.FC = ({ data }) => { - const groupedItems = groupBy(data, 'node_id'); - const chartData = Object.keys(groupedItems).map(nodeId => { - const items = groupedItems[nodeId]; - const dailyData = calculateDailyValues(items); +interface ChartGridProps { + data: NodeMetrics[] + } + + export const ChartGrid: React.FC = ({ data }) => { + const [processedData, setProcessedData] = useState([]); + const [isLoading, setIsLoading] = useState(true); + + React.useEffect(() => { + const processData = () => { + const groupedItems = groupBy(data, 'node_id'); + + const processed = Object.keys(groupedItems).map(nodeId => { + const items = groupedItems[nodeId]; + const dailyData = calculateDailyValues(items); + + return { + nodeId, + title: nodeId.split('-')[0], + subnetId: items[0].subnet_id, + dailyData: dailyData, + failureRateSum: dailyData.reduce((sum, item) => sum + item.failureRate, 0), + failureRateAvg: computeAverageFailureRate(dailyData.map(elem => elem.failureRate)), + }; + }).sort((a, b) => b.failureRateSum - a.failureRateSum); + + setProcessedData(processed); + setIsLoading(false); + }; + + processData(); + }, [data]); + + return ( + + {isLoading ? ( + + + + ) : ( + processedData.slice(0, 10).map(({ nodeId, title, subnetId, dailyData, failureRateAvg }, index) => ( + + + + + + + {nodeId} + + + + + + + + new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }).replace(" ", "\n") }]} + series={[ + { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, + ]} + dataset={dailyData} + height={400} + /> + + + + + + + )) + )} + + ); +}; +interface StackedChartProps { + data: NodeMetrics[]; + name: string | null; + } - return { - nodeId, - title: nodeId.split('-')[0], - subnetId: items[0].subnet_id, - dailyData: dailyData, - failureRateSum: dailyData.reduce((sum, item) => sum + item.failureRate, 0), - failureRateAvg: computeAverageFailureRate(dailyData.map((elem) => elem.failureRate)), - }; - }).sort((a, b) => b.failureRateSum - a.failureRateSum); - - return ( - - {chartData.map(({ nodeId, title, subnetId, dailyData, failureRateAvg }, index) => ( - - - - - - - {nodeId} - - - - - - - - { - const formatted = new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }).replace(" ", "\n") - return formatted - }}]} - series={[ - { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, - ]} - dataset={dailyData} - height={400} - /> - - - - - - - ))} - - - ); + export const StackedChart: React.FC = ({ data, name }) => { + const [stackOrder, setStackOrder] = useState('ascending'); + const [isLoading, setIsLoading] = useState(true); + const [modifiedSeries, setModifiedSeries] = useState([]); + + React.useEffect(() => { + const processData = () => { + const nodesGrouped = groupBy(data, 'node_id'); + + const chartData = Object.keys(nodesGrouped).flatMap(nodeId => { + const items = nodesGrouped[nodeId]; + const dailyData = calculateDailyValues(items); + return { + data: dailyData.map(daily => daily.failureRate), + stack: 'A', + label: nodeId, + }; + }); + + const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; + + setModifiedSeries(series); + setIsLoading(false); + }; + + processData(); + }, [data, stackOrder]); + + return ( + + + + + + Subnet: {name} + + + + + + {isLoading ? ( + + + + ) : ( + + + `${value}%`, + label: 'Sum nodes failure rate', + }, + ]} + sx={{ + p: 2, + [`.${axisClasses.left} .${axisClasses.label}`]: { + transform: 'translateX(-35px)', + }, + }} + borderRadius={9} + series={modifiedSeries} + height={800} + /> + + + )} + + + + ); }; -export default ChartGrid; + export const TestChart: React.FC = ({ data, name }) => { + + return ( + + + + + + Subnet: {name} + + + + + + + + ); + }; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx index 5d5595987..7c12c92e8 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx @@ -1,83 +1,122 @@ -// src/components/Drawer.tsx - -import React, { useState } from 'react'; -import { Drawer as MUIDrawer, List, ListItem, Typography, Menu, MenuItem, Box, Theme, IconButton, Toolbar } from '@mui/material'; +import React from 'react'; +import { + Drawer as MUIDrawer, + List, + Typography, + MenuItem, + Theme, + Accordion, + AccordionSummary, + AccordionDetails, + FormControl, + InputLabel, + Select, + ListItem, + IconButton, + Toolbar, + Button, + ListItemButton, +} from '@mui/material'; +import { Link } from 'react-router-dom'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import { Filters } from './FilterBar'; import { SxProps } from '@mui/system'; -import Logo from '../assets/icp_logo.svg'; // Import SVG as React component +import Logo from '../assets/icp_logo.svg'; interface DrawerProps { subnets: Set; + nodeProviders: Set; drawerWidth: number; theme: Theme; - onSubnetSelect: (subnet: string) => void; + setFilters: React.Dispatch>; } -const Drawer: React.FC = ({ subnets, drawerWidth, theme, onSubnetSelect }) => { - const [drawerOpen, setDrawerOpen] = useState(false); - const [menuAnchorEl, setMenuAnchorEl] = useState(null); - - const handleDrawerOpen = () => { - setDrawerOpen(true); - }; - - const handleDrawerClose = () => { - setDrawerOpen(false); - }; - - const handleMenuOpen = (event: React.MouseEvent) => { - setMenuAnchorEl(event.currentTarget); - }; +const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth, theme, setFilters }) => { - const handleMenuClose = () => { - setMenuAnchorEl(null); + const handleSubnetSelect = (subnet: string) => { + setFilters((prev) => ({ ...prev, subnet, nodeProvider: null })); }; - const handleSubnetSelect = (subnet: string) => { - onSubnetSelect(subnet); - handleMenuClose(); + const handleNodeProviderSelect = (nodeProvider: string) => { + setFilters((prev) => ({ ...prev, nodeProvider, subnet: null })); }; return ( - <> - - - - - Logo - - - - - - - Subnets - - - - - handleSubnetSelect('')}> - None - - {Array.from(subnets).map((subnet, index) => ( - handleSubnetSelect(subnet)}> - {subnet} - - ))} - - + + + + + Logo + + + + + + + + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + Subnets + + + + + + {Array.from(subnets).map((subnet, index) => ( + + + handleSubnetSelect(subnet)}> + {subnet.toString().split("-")[0]} + + + + ))} + + + + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + Node Providers + + + + {Array.from(nodeProviders).map((nodeProvider, index) => ( + handleNodeProviderSelect(nodeProvider)}> + + {nodeProvider.toString().split("-")[0]} + + + ))} + + + + + ); }; export default Drawer; + + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx index 55c5f8f97..71ad6fc9a 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx @@ -9,7 +9,8 @@ import ArrowRightIcon from '@mui/icons-material/ArrowRight'; export interface Filters { dateStart: Date; dateEnd: Date; - subnet: string; // Use string instead of String + subnet: string | null; + nodeProvider: string | null; } interface FilterBarProps { From 5ad9b0c5e3107fa5e5466721477f9e7d3e524f50 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 30 Jul 2024 21:49:47 +0200 Subject: [PATCH 05/40] Sync with prod --- .../package-lock.json | 9637 +++++++++++++---- .../.eslintrc.json | 6 + .../eslint.config.js | 13 + .../package.json | 13 + .../src/App.tsx | 93 +- .../src/components/ChartComponent.tsx | 20 - .../src/components/ChartGrid.tsx | 238 - .../src/components/Drawer.tsx | 141 +- .../src/components/FilterBar.tsx | 13 +- .../src/components/Gauge.tsx | 63 + .../src/components/Header.tsx | 8 +- .../src/components/NodeList.tsx | 101 + .../src/components/RewardTable.tsx | 47 + .../src/components/SubnetChart.tsx | 72 + .../src/models/NodeMetrics.tsx | 82 +- .../src/utils/utils.tsx | 78 + 16 files changed, 8333 insertions(+), 2292 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.eslintrc.json create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/eslint.config.js delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx diff --git a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json index be9fd1d3c..c1bff0880 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json +++ b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json @@ -39,9 +39,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", - "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.0.tgz", + "integrity": "sha512-P4fwKI2mjEb3ZU5cnMJzvRsRKGBUcs8jvxIoRmr6ufAY9Xk2Bz7JubRTTivkw55c7WQJfTECeqYVa+HZ0FzREg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -77,12 +77,39 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/eslint-parser": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz", + "integrity": "sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==", + "dev": true, + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/@babel/generator": { - "version": "7.24.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", - "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", "dependencies": { - "@babel/types": "^7.24.9", + "@babel/types": "^7.25.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -91,6 +118,31 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", @@ -107,35 +159,68 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", + "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.0", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.0.tgz", + "integrity": "sha512-q0T+dknZS+L5LDazIP+02gEZITG5unzvb6yIjcmj5i0eFrs5ToBV2m2JGH4EsE/gtP8ygEGLGApBgRIZkTm7zg==", + "dev": true, "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@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/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -154,16 +239,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", - "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.0.tgz", + "integrity": "sha512-bIkOa2ZJYn7FHnepzr5iX9Kmz8FjIz4UKzJ9zhX3dnYuVW0xul9RuR3skBfoLu+FPTQw90EHW9rJsSZhyLQ3fQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -172,6 +256,18 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-plugin-utils": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", @@ -181,6 +277,40 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/helper-simple-access": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", @@ -194,11 +324,13 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, "dependencies": { + "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" }, "engines": { @@ -230,6 +362,20 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helpers": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", @@ -258,9 +404,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.0.tgz", + "integrity": "sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -268,2419 +414,6455 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", - "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.0.tgz", + "integrity": "sha512-dG0aApncVQwAUJa8tP1VHTnmU67BeIQvKafd3raEx315H54FfkZSz3B/TT+33ZQAjatGJA79gZqTtqL5QZUKXw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", - "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "dev": true, "dependencies": { - "regenerator-runtime": "^0.14.0" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/template": { + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/traverse": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", - "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/types": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", - "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", + "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", + "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-decorators": "^7.24.7" }, "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dfinity/agent": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.7.tgz", - "integrity": "sha512-w34yvlUTpPBG8nLOD0t/ao3k2xonOFq4QGvfJ1HiS/nIggdza/3xC3nLBszGrjVYWj1jqu8BLFvQXCAeWin75A==", + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dev": true, "dependencies": { - "base64-arraybuffer": "^0.2.0", - "bignumber.js": "^9.0.0", - "borc": "^2.1.1", - "js-sha256": "0.9.0", - "simple-cbor": "^0.4.1", - "ts-node": "^10.8.2" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@dfinity/candid": "^0.15.7", - "@dfinity/principal": "^0.15.7" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dfinity/candid": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.7.tgz", - "integrity": "sha512-lTcjK/xrSyT7wvUQ2pApG+yklQAwxaofQ04D1IWv0/8gKbY0eUbh8G2w6+CypJ15Hb1CH24ijUj8nWdeX/z3jg==", + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "dev": true, "dependencies": { - "ts-node": "^10.8.2" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@dfinity/principal": { - "version": "0.15.7", - "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.7.tgz", - "integrity": "sha512-6/AkYzpGEH6Jw/0+B/EeeQn+5u2GDDvRLt1kQPhIG4txQYFnOy04H3VvyrymmfAj6/CXUgrOrux6OxgYSLYVJg==", + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dev": true, "dependencies": { - "js-sha256": "^0.9.0", - "ts-node": "^10.8.2" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", - "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.2.0", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/cache": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", - "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, "dependencies": { - "@emotion/memoize": "^0.9.0", - "@emotion/sheet": "^1.4.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "stylis": "4.2.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", - "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, "dependencies": { - "@emotion/memoize": "^0.9.0" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" - }, - "node_modules/@emotion/react": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", - "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/cache": "^11.13.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0", - "@emotion/weak-memoize": "^0.4.0", - "hoist-non-react-statics": "^3.3.1" + "@babel/helper-plugin-utils": "^7.14.5" }, - "peerDependencies": { - "react": ">=16.8.0" + "engines": { + "node": ">=6.9.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/serialize": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", - "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", + "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", + "dev": true, "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.9.0", - "@emotion/utils": "^1.4.0", - "csstype": "^3.0.2" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" - }, - "node_modules/@emotion/styled": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", - "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.12.0", - "@emotion/is-prop-valid": "^1.3.0", - "@emotion/serialize": "^1.3.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", - "@emotion/utils": "^1.4.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/unitless": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", - "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", - "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, "peerDependencies": { - "react": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@emotion/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" - }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", + "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", "dev": true, - "optional": true, - "os": [ - "netbsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", + "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", "dev": true, - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.0" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "dev": true, - "optional": true, - "os": [ - "sunos" - ], + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@floating-ui/core": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", - "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dev": true, "dependencies": { - "@floating-ui/utils": "^0.2.5" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, - "node_modules/@floating-ui/dom": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", - "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", + "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "dev": true, "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.5" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dev": true, "dependencies": { - "@floating-ui/dom": "^1.0.0" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", - "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@kurkle/color": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", - "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", - "peer": true - }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", - "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@floating-ui/react-dom": "^2.0.8", - "@mui/types": "^7.2.14", - "@mui/utils": "^5.15.14", - "@popperjs/core": "^2.11.8", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/core-downloads-tracker": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", - "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/icons-material": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.5.tgz", - "integrity": "sha512-bn88xxU/J9UV0s6+eutq7o3TTOrOlbCX+KshFb8kxgIxJZZfYz3JbAXVMivvoMF4Md6jCVUzM9HEkf4Ajab4tw==", + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/lab": { - "version": "5.0.0-alpha.172", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.172.tgz", - "integrity": "sha512-stpa3WTsDE1HamFR4eeS6Bhxalm+u9FhzzNph/PrDMdWSRBHlJs2mqvZ6FEoO22O7MOCwNMqbXTkvEwsyEf0ew==", + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz", + "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.40", - "@mui/system": "^5.16.1", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.1", - "clsx": "^2.1.0", - "prop-types": "^15.8.1" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-flow": "^7.24.7" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@mui/material": ">=5.15.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/material": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", - "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.4", - "@mui/system": "^5.16.4", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", - "@popperjs/core": "^2.11.8", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1", - "react-is": "^18.3.1", - "react-transition-group": "^4.4.5" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/private-theming": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", - "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.4", - "prop-types": "^15.8.1" + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/styled-engine": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", - "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.11.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/system": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", - "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.4", - "@mui/styled-engine": "^5.16.4", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", - "clsx": "^2.1.0", - "csstype": "^3.1.3", - "prop-types": "^15.8.1" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "node": ">=6.9.0" }, "peerDependencies": { - "@emotion/react": "^11.5.0", - "@emotion/styled": "^11.3.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/types": { - "version": "7.2.15", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", - "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0" + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/utils": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", - "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.23.9", - "@types/prop-types": "^15.7.12", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-is": "^18.3.1" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { - "node": ">=12.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@mui/x-charts": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.11.0.tgz", - "integrity": "sha512-qNmrXk2eKoXOuxyLX6Vg4paWPcRttnIQx8hxuHc/avvGzX55kS4s69G8NIG0mtqygtDMcYJPDGNCJOlmkp1uAg==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.24.8", - "@mui/base": "^5.0.0-beta.40", - "@mui/system": "^5.16.2", - "@mui/utils": "^5.16.2", - "@react-spring/rafz": "^9.7.3", - "@react-spring/web": "^9.7.3", - "clsx": "^2.1.1", - "d3-color": "^3.1.0", - "d3-delaunay": "^6.0.4", - "d3-interpolate": "^3.0.1", - "d3-scale": "^4.0.2", - "d3-shape": "^3.2.0", - "prop-types": "^15.8.1" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" }, "peerDependencies": { - "@emotion/react": "^11.9.0", - "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@mui/x-date-pickers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.11.0.tgz", - "integrity": "sha512-+zPWs1dwe7J1nZ2iFhTgCae31BLMYMQ2VtQfHxx21Dh6gbBRy/U7YJZg1LdhfQyE093S3e4A5uMZ6PUWdne7iA==", + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.24.8", - "@mui/base": "^5.0.0-beta.40", - "@mui/system": "^5.16.2", - "@mui/utils": "^5.16.2", - "@types/react-transition-group": "^4.4.10", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@emotion/react": "^11.9.0", - "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", - "date-fns": "^2.25.0 || ^3.2.0", - "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", - "dayjs": "^1.10.7", - "luxon": "^3.0.2", - "moment": "^2.29.4", + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz", + "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", + "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", + "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.0.tgz", + "integrity": "sha512-LZicxFzHIw+Sa3pzgMgSz6gdpsdkfiMObHUzhSIrwKF0+/rP/nuR49u79pSS+zIFJ1FeGeqQD2Dq4QGFbOVvSw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.0.tgz", + "integrity": "sha512-vYAA8PrCOeZfG4D87hmw1KJ1BPubghXP1e2MacRFwECGNKL76dkA38JEwYllbvQCpf/kLxsTtir0b8MtxKoVCw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.0", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.0", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.0", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.0", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.0", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.1.tgz", + "integrity": "sha512-LrHHoWq08ZpmmFqBAzN+hUdWwy5zt7FGa/hVwMcOqW6OVtwqaoD5utfuGYU87JYxdZgLUvktAsn37j/sYR9siA==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.0.tgz", + "integrity": "sha512-LcnxQSsd9aXOIgmmSpvZ/1yo46ra2ESYyqLcryaBZOghxy5qqOBjvCWP5JfkI8yl9rlxRgdLTTMCQQRcN2hdCg==", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dfinity/agent": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-0.15.7.tgz", + "integrity": "sha512-w34yvlUTpPBG8nLOD0t/ao3k2xonOFq4QGvfJ1HiS/nIggdza/3xC3nLBszGrjVYWj1jqu8BLFvQXCAeWin75A==", + "dependencies": { + "base64-arraybuffer": "^0.2.0", + "bignumber.js": "^9.0.0", + "borc": "^2.1.1", + "js-sha256": "0.9.0", + "simple-cbor": "^0.4.1", + "ts-node": "^10.8.2" + }, + "peerDependencies": { + "@dfinity/candid": "^0.15.7", + "@dfinity/principal": "^0.15.7" + } + }, + "node_modules/@dfinity/candid": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/candid/-/candid-0.15.7.tgz", + "integrity": "sha512-lTcjK/xrSyT7wvUQ2pApG+yklQAwxaofQ04D1IWv0/8gKbY0eUbh8G2w6+CypJ15Hb1CH24ijUj8nWdeX/z3jg==", + "dependencies": { + "ts-node": "^10.8.2" + } + }, + "node_modules/@dfinity/principal": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@dfinity/principal/-/principal-0.15.7.tgz", + "integrity": "sha512-6/AkYzpGEH6Jw/0+B/EeeQn+5u2GDDvRLt1kQPhIG4txQYFnOy04H3VvyrymmfAj6/CXUgrOrux6OxgYSLYVJg==", + "dependencies": { + "js-sha256": "^0.9.0", + "ts-node": "^10.8.2" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz", + "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/react": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.0.tgz", + "integrity": "sha512-WkL+bw1REC2VNV1goQyfxjx1GYJkcc23CRQkXX+vZNLINyfI7o+uUn/rTGPt/xJ3bJHd5GcljgnxHf4wRw5VWQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.0.tgz", + "integrity": "sha512-jACuBa9SlYajnpIVXB+XOXnfJHyckDfe6fOpORIM6yhBDlqGuExvDdZYHDQGoDf3bZXGv7tNr+LpLjJqiEQ6EA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.9.0", + "@emotion/utils": "^1.4.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz", + "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "dependencies": { + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "peer": true + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", + "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.16.5", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.5.tgz", + "integrity": "sha512-bn88xxU/J9UV0s6+eutq7o3TTOrOlbCX+KshFb8kxgIxJZZfYz3JbAXVMivvoMF4Md6jCVUzM9HEkf4Ajab4tw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.172", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.172.tgz", + "integrity": "sha512-stpa3WTsDE1HamFR4eeS6Bhxalm+u9FhzzNph/PrDMdWSRBHlJs2mqvZ6FEoO22O7MOCwNMqbXTkvEwsyEf0ew==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/system": "^5.16.1", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.1", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": ">=5.15.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", + "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.4", + "@mui/system": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", + "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.4", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", + "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", + "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.4", + "@mui/styled-engine": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", + "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.11.0.tgz", + "integrity": "sha512-qNmrXk2eKoXOuxyLX6Vg4paWPcRttnIQx8hxuHc/avvGzX55kS4s69G8NIG0mtqygtDMcYJPDGNCJOlmkp1uAg==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@react-spring/rafz": "^9.7.3", + "@react-spring/web": "^9.7.3", + "clsx": "^2.1.1", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.11.0.tgz", + "integrity": "sha512-+zPWs1dwe7J1nZ2iFhTgCae31BLMYMQ2VtQfHxx21Dh6gbBRy/U7YJZg1LdhfQyE093S3e4A5uMZ6PUWdne7iA==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers-pro": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-7.11.0.tgz", + "integrity": "sha512-qCHsoNoFgldGxlJE77vL18lhbV7Qg15UFkqCQWV8KbUd5PLrK1kaIf2ddMwLGKJKl4sxSU6rgH/yat95HDdggA==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.16.2", + "@mui/utils": "^5.16.2", + "@mui/x-date-pickers": "7.11.0", + "@mui/x-license": "7.11.0", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", "moment-hijri": "^2.1.2", "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "date-fns": { - "optional": true - }, - "date-fns-jalali": { - "optional": true - }, - "dayjs": { - "optional": true - }, - "luxon": { - "optional": true - }, - "moment": { - "optional": true - }, - "moment-hijri": { - "optional": true - }, - "moment-jalaali": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-license": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.11.0.tgz", + "integrity": "sha512-4YOfiJ2CDque+nP4MNFU6eNiw2bf9rFGZtN9s0XRWXIaIoLKXICWcMx/PjYpqtLdSGG8eFe+EINX0oxiWC9XSg==", + "dependencies": { + "@babel/runtime": "^7.24.8", + "@mui/utils": "^5.16.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@next/env": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz", + "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz", + "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", + "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", + "dependencies": { + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", + "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", + "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", + "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", + "dependencies": { + "@react-spring/rafz": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", + "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", + "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", + "dependencies": { + "@react-spring/animated": "~9.7.4", + "@react-spring/core": "~9.7.4", + "@react-spring/shared": "~9.7.4", + "@react-spring/types": "~9.7.4" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", + "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", + "dev": true + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true, + "peer": true + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", + "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.24.5", + "@babel/plugin-transform-react-jsx-self": "^7.24.5", + "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", + "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", + "dev": true + }, + "node_modules/babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "devOptional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/borc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", + "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "dependencies": { + "bignumber.js": "^9.0.0", + "buffer": "^5.5.0", + "commander": "^2.15.0", + "ieee754": "^1.1.13", + "iso-url": "~0.4.7", + "json-text-sequence": "~0.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "devOptional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chart.js": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "peer": true, + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "devOptional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "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/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { "optional": true } } }, - "node_modules/@mui/x-date-pickers-pro": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-7.11.0.tgz", - "integrity": "sha512-qCHsoNoFgldGxlJE77vL18lhbV7Qg15UFkqCQWV8KbUd5PLrK1kaIf2ddMwLGKJKl4sxSU6rgH/yat95HDdggA==", + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.24.8", - "@mui/base": "^5.0.0-beta.40", - "@mui/system": "^5.16.2", - "@mui/utils": "^5.16.2", - "@mui/x-date-pickers": "7.11.0", - "@mui/x-license": "7.11.0", - "clsx": "^2.1.1", - "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" }, - "peerDependencies": { - "@emotion/react": "^11.9.0", - "@emotion/styled": "^11.8.1", - "@mui/material": "^5.15.14", - "date-fns": "^2.25.0 || ^3.2.0", - "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0", - "dayjs": "^1.10.7", - "luxon": "^3.0.2", - "moment": "^2.29.4", - "moment-hijri": "^2.1.2", - "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "date-fns": { - "optional": true - }, - "date-fns-jalali": { - "optional": true - }, - "dayjs": { - "optional": true - }, - "luxon": { - "optional": true - }, - "moment": { - "optional": true - }, - "moment-hijri": { - "optional": true - }, - "moment-jalaali": { - "optional": true - } + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@mui/x-license": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.11.0.tgz", - "integrity": "sha512-4YOfiJ2CDque+nP4MNFU6eNiw2bf9rFGZtN9s0XRWXIaIoLKXICWcMx/PjYpqtLdSGG8eFe+EINX0oxiWC9XSg==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.24.8", - "@mui/utils": "^5.16.2" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" }, - "peerDependencies": { - "react": "^17.0.0 || ^18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@next/env": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz", - "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==" + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz", - "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], + "node_modules/delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", + "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, "engines": { - "node": ">= 10" + "node": ">= 0.4" } }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", - "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, "engines": { - "node": ">= 10" + "node": ">= 0.4" } }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", - "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, "engines": { - "node": ">= 10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", - "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">= 10" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", - "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, "engines": { - "node": ">= 10" + "node": ">=6" } }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", - "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { - "node": ">= 10" + "node": ">=0.8.0" } }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", - "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, "engines": { - "node": ">= 10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", - "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, "engines": { - "node": ">= 10" + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" } }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", - "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, "engines": { - "node": ">= 10" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/@react-spring/animated": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.4.tgz", - "integrity": "sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==", + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dev": true, "dependencies": { - "@react-spring/shared": "~9.7.4", - "@react-spring/types": "~9.7.4" + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" } }, - "node_modules/@react-spring/core": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.4.tgz", - "integrity": "sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==", + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, "dependencies": { - "@react-spring/animated": "~9.7.4", - "@react-spring/shared": "~9.7.4", - "@react-spring/types": "~9.7.4" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-spring/donate" + "engines": { + "node": ">=4" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/@react-spring/rafz": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.4.tgz", - "integrity": "sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==" + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } }, - "node_modules/@react-spring/shared": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.4.tgz", - "integrity": "sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==", + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", + "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "dev": true, "dependencies": { - "@react-spring/rafz": "~9.7.4", - "@react-spring/types": "~9.7.4" + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.9.1", + "axobject-query": "~3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" + }, + "engines": { + "node": ">=4.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/@react-spring/types": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.4.tgz", - "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" - }, - "node_modules/@react-spring/web": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.4.tgz", - "integrity": "sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==", + "node_modules/eslint-plugin-react": { + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", + "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", + "dev": true, "dependencies": { - "@react-spring/animated": "~9.7.4", - "@react-spring/core": "~9.7.4", - "@react-spring/shared": "~9.7.4", - "@react-spring/types": "~9.7.4" + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/@remix-run/router": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", - "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, "engines": { - "node": ">=14.0.0" + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" - }, - "node_modules/@swc/helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, "dependencies": { - "@swc/counter": "^0.1.3", - "tslib": "^2.4.0" + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "peer": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, "dependencies": { - "@types/d3-color": "*" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" - }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, "dependencies": { - "@types/d3-time": "*" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, "dependencies": { - "@types/d3-path": "*" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true }, - "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "peer": true, - "dependencies": { - "undici-types": "~5.26.4" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "peer": true, "dependencies": { - "@types/react": "*" + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", - "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", - "dependencies": { - "@types/react": "*" + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" } }, - "node_modules/@vitejs/plugin-react": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", - "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "peer": true, "dependencies": { - "@babel/core": "^7.24.5", - "@babel/plugin-transform-react-jsx-self": "^7.24.5", - "@babel/plugin-transform-react-jsx-source": "^7.24.1", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "bin": { - "acorn": "bin/acorn" + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10" } }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "dependencies": { - "acorn": "^8.11.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=4.0" } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=4.0" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", "engines": { - "node": ">=10", - "npm": ">=6" + "node": ">=6.0.0" } }, - "node_modules/base64-arraybuffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", - "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, "engines": { - "node": ">= 0.6.0" + "node": ">=8.6.0" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "peer": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, "engines": { - "node": "*" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/borc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", - "integrity": "sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w==", + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "peer": true, "dependencies": { - "bignumber.js": "^9.0.0", - "buffer": "^5.5.0", - "commander": "^2.15.0", - "ieee754": "^1.1.13", - "iso-url": "~0.4.7", - "json-text-sequence": "~0.1.0", - "readable-stream": "^3.6.0" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "devOptional": true, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" + "is-callable": "^1.1.3" } }, - "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "peer": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, "dependencies": { - "streamsearch": "^1.1.0" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "engines": { - "node": ">=10.16.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001643", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", - "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "is-glob": "^4.0.1" }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "engines": { "node": ">=4" } }, - "node_modules/chart.js": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", - "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", - "peer": true, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, "dependencies": { - "@kurkle/color": "^0.3.0" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { - "pnpm": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "devOptional": true, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">= 8.10.0" + "node": ">=10" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "dependencies": { - "color-name": "1.1.3" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/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/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { - "internmap": "1 - 2" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, "engines": { - "node": ">=12" + "node": ">= 4" } }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "devOptional": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { - "delaunator": "5" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "engines": { - "node": ">=12" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, "engines": { - "node": ">=12" + "node": ">=0.8.19" } }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "peer": true, "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "engines": { - "node": ">=12" - } + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", "engines": { "node": ">=12" } }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, "dependencies": { - "d3-array": "2 - 3" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, "dependencies": { - "d3-time": "1 - 3" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "engines": { - "node": ">=12" - } + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.21.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.11" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" + "has-bigints": "^1.0.1" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" - }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, "dependencies": { - "robust-predicates": "^3.0.2" - } - }, - "node_modules/delimit-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", - "integrity": "sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ==" - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "binary-extensions": "^2.0.0" + }, "engines": { - "node": ">=0.3.1" + "node": ">=8" } }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://dotenvx.com" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", - "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", - "dev": true - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dependencies": { - "is-arrayish": "^0.2.1" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/fast-equals": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "devOptional": true, "dependencies": { - "to-regex-range": "^5.0.1" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "devOptional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, "dependencies": { - "function-bind": "^1.1.2" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "dependencies": { - "react-is": "^16.7.0" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "devOptional": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, "dependencies": { - "hasown": "^2.0.2" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -2689,35 +6871,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, - "engines": { - "node": ">=0.12.0" - } + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/iso-url": { "version": "0.4.7", @@ -2727,6 +6891,19 @@ "node": ">=10" } }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, "node_modules/js-sha256": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", @@ -2737,6 +6914,18 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -2748,11 +6937,29 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, "node_modules/json-text-sequence": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", @@ -2773,16 +6980,98 @@ "node": ">=6" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2808,6 +7097,49 @@ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2830,6 +7162,18 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/next": { "version": "14.2.5", "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz", @@ -2929,6 +7273,181 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "peer": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2957,6 +7476,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -2987,6 +7534,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", @@ -3012,7 +7568,16 @@ "source-map-js": "^1.2.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" } }, "node_modules/prop-types": { @@ -3030,6 +7595,35 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -3195,11 +7789,115 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -3224,6 +7922,33 @@ "node": ">=4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/robust-predicates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", @@ -3245,6 +7970,47 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3264,6 +8030,23 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sass": { "version": "1.77.8", "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", @@ -3298,11 +8081,91 @@ "semver": "bin/semver.js" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "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.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/simple-cbor": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/simple-cbor/-/simple-cbor-0.4.1.tgz", "integrity": "sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==" }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -3311,28 +8174,174 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", + "dev": true + }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, "engines": { - "node": ">=10.0.0" + "node": ">=4" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/styled-jsx": { @@ -3384,6 +8393,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -3413,6 +8428,18 @@ "resolved": "src/trustworthy-node-metrics-frontend", "link": true }, + "node_modules/ts-api-utils": { + "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" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -3455,21 +8482,426 @@ } } }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.18.0.tgz", + "integrity": "sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.18.0", + "@typescript-eslint/parser": "7.18.0", + "@typescript-eslint/utils": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typescript-eslint/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "semver": "bin/semver.js" }, "engines": { - "node": ">=14.17" + "node": ">=10" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/undici-types": { @@ -3478,6 +8910,46 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "peer": true }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", @@ -3508,6 +8980,15 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -3603,6 +9084,116 @@ "vite": ">= 2.7" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "peer": true + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -3625,6 +9216,18 @@ "node": ">=6" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "src/trustworthy-node-metrics-frontend": { "version": "0.0.0", "dependencies": { @@ -3649,15 +9252,293 @@ "recharts": "^2.12.7" }, "devDependencies": { + "@eslint/js": "^9.8.0", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", "@vitejs/plugin-react": "^4.0.1", "dotenv": "^16.3.1", + "eslint": "^8.0.0", + "eslint-config-react-app": "^7.0.1", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^4.6.2", + "globals": "^15.8.0", "sass": "^1.63.6", "typescript": "^5.1.3", + "typescript-eslint": "^7.18.0", "vite": "^4.3.9", "vite-plugin-environment": "^1.1.3" } + }, + "src/trustworthy-node-metrics-frontend/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/@eslint/js": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", + "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "src/trustworthy-node-metrics-frontend/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/eslint": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", + "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.8.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/globals": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", + "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "src/trustworthy-node-metrics-frontend/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } } } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.eslintrc.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.eslintrc.json new file mode 100644 index 000000000..acb2e2a90 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "react-app", + "plugin:react-hooks/recommended" + ] + } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/eslint.config.js b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/eslint.config.js new file mode 100644 index 000000000..c69209327 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/eslint.config.js @@ -0,0 +1,13 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; +import pluginReact from "eslint-plugin-react"; + + +export default [ + {files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"]}, + {languageOptions: { globals: globals.browser }}, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + pluginReact.configs.flat.recommended, +]; \ No newline at end of file diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json index a47ee681d..75ff6fc56 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/package.json @@ -10,6 +10,12 @@ "build": "tsc && vite build", "format": "prettier --write \"src/**/*.{json,js,jsx,ts,tsx,css,scss}\"" }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, "dependencies": { "@dfinity/agent": "^0.15.7", "@dfinity/candid": "^0.15.7", @@ -32,12 +38,19 @@ "recharts": "^2.12.7" }, "devDependencies": { + "@eslint/js": "^9.8.0", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", "@vitejs/plugin-react": "^4.0.1", "dotenv": "^16.3.1", + "eslint": "^8.0.0", + "eslint-config-react-app": "^7.0.1", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^4.6.2", + "globals": "^15.8.0", "sass": "^1.63.6", "typescript": "^5.1.3", + "typescript-eslint": "^7.18.0", "vite": "^4.3.9", "vite-plugin-environment": "^1.1.3" } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index 1d8e21de3..1a83175c4 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -1,14 +1,15 @@ import React, { useState, useEffect } from 'react'; import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; -import FilterBar, { Filters } from './components/FilterBar'; +import FilterBar, { PeriodFilter } from './components/FilterBar'; import Drawer from './components/Drawer'; import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; // Adjust the path as needed import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; -import { NodeMetrics } from './models/NodeMetrics'; -import { ChartGrid } from './components/ChartGrid'; -import { StackedChart } from './components/ChartGrid'; +import { DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; +import { NodeList } from './components/NodeList'; import Header from './components/Header'; +import { calculateDailyValues, groupBy } from './utils/utils'; +import { SubnetChart } from './components/SubnetChart'; const darkTheme = createTheme({ palette: { @@ -17,18 +18,28 @@ const darkTheme = createTheme({ }, }); +const LoadingIndicator: React.FC = () => ( + + + +); + function App() { const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); - const [filters, setFilters] = useState({ + const [periodFilter, setPeriodFilter] = useState({ dateStart: thirtyDaysAgo, - dateEnd: new Date(), - subnet: null, - nodeProvider: null + dateEnd: new Date() }); - const [data, setData] = useState([]); - const [filteredData, setFilteredData] = useState([]); + const [nodeMetrics, setNodeMetrics] = useState([]); const [subnets, setSubnets] = useState>(new Set()); const [nodeProviders, setNodeProviders] = useState>(new Set()); const [isLoading, setIsLoading] = useState(true); @@ -38,6 +49,7 @@ function App() { useEffect(() => { const fetchNodes = async () => { try { + setIsLoading(true); const request: SubnetNodeMetricsArgs = { ts: [], subnet_id: [], @@ -58,9 +70,27 @@ function App() { ); }) }); - const subnets: Set = new Set(metrics.map(metric => metric.subnet_id.toText())); + const metricsInPeriod = metrics.filter((metrics) => { + const metricsDate = metrics.date; + const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; + return isDateInRange; + }); + + const subnets: Set = new Set(metrics.map(metric => metric.subnetId.toText())); + + const grouped = groupBy(metricsInPeriod, 'nodeId'); + const groupedMetrics = Object.keys(grouped).map(nodeId => { + const items = grouped[nodeId]; + const dailyData = calculateDailyValues(items); - setData(metrics); + return new DashboardNodeMetrics( + nodeId, + dailyData, + ); + }) + .sort((a, b) => b.failureRateAvg - a.failureRateAvg); + + setNodeMetrics(groupedMetrics); setSubnets(subnets); setIsLoading(false); } else { @@ -72,34 +102,12 @@ function App() { }; fetchNodes(); - }, []); - - useEffect(() => { - const filterData = () => { - const f = data.filter((metrics) => { - const metricsDate = metrics.date; - const isDateInRange = metricsDate >= filters.dateStart && metricsDate <= filters.dateEnd; - - if (filters.subnet !== null) { - return metrics.subnet_id.toText() === filters.subnet && isDateInRange; - } - - return isDateInRange; - }); - - setFilteredData(f); - } - filterData(); - }, [filters, data]); + }, [periodFilter]); if (error) { return
Error: {error}
; } - if (isLoading) { - return - } - return ( @@ -109,8 +117,6 @@ function App() { subnets={subnets} nodeProviders={nodeProviders} drawerWidth={drawerWidth} - theme={darkTheme} - setFilters={setFilters} /> } /> - } /> - } /> - } /> + ) : ()} + /> + ) : ()} + /> diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx deleted file mode 100644 index 83b8b3413..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartComponent.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { Line } from 'react-chartjs-2'; -import { Box } from '@mui/material'; -import { NodeMetrics } from '../models/NodeMetrics'; - - -interface ChartProps { - data: NodeMetrics[]; - name: string | null; - } - - -const ChartComponent: React.FC = ({ data }) => { - return ( - - - ); -}; - -export default ChartComponent; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx deleted file mode 100644 index 0811fe859..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ChartGrid.tsx +++ /dev/null @@ -1,238 +0,0 @@ -import React, { useState } from 'react'; -import { Box, CircularProgress, Grid, Paper, Stack, Typography } from '@mui/material'; -import { axisClasses, BarChart, StackOrderType } from '@mui/x-charts'; -import { NodeMetrics } from '../models/NodeMetrics'; -import { styled } from '@mui/material/styles'; -import Divider from '@mui/material/Divider'; - -const Root = styled('div')(({ theme }) => ({ - width: '100%', - ...theme.typography.body2, - color: theme.palette.text.secondary, - '& > :not(style) ~ :not(style)': { - marginTop: theme.spacing(2), - }, - })); - -function groupBy(items: T[], key: K): Record { - return items.reduce((result, item) => { - const groupKey = String(item[key]); - if (!result[groupKey]) { - result[groupKey] = []; - } - result[groupKey].push(item); - return result; - }, {} as Record); -} - -const calculateDailyValues = (items: NodeMetrics[]) => { - const dailyValues = []; - let previousTotals = { num_block_failures_total: 0.0, num_blocks_proposed_total: 0.0 }; - - items.sort((a, b) => a.date.getTime() - b.date.getTime()); - - for (const item of items) { - const currentDate = item.date; - const currentTotals = { - num_block_failures_total: Number(item.num_block_failures_total), - num_blocks_proposed_total: Number(item.num_blocks_proposed_total), - }; - - if (previousTotals.num_block_failures_total || previousTotals.num_blocks_proposed_total) { - const dailyFailures = currentTotals.num_block_failures_total - previousTotals.num_block_failures_total; - const dailyProposed = currentTotals.num_blocks_proposed_total - previousTotals.num_blocks_proposed_total; - - dailyValues.push({ - date: currentDate, - num_block_failures_day: currentTotals.num_block_failures_total - previousTotals.num_block_failures_total, - num_blocks_proposed_day: currentTotals.num_blocks_proposed_total - previousTotals.num_blocks_proposed_total, - failureRate: dailyFailures / (dailyProposed + dailyFailures) * 100, - }); - } - - previousTotals = currentTotals; - } - - return dailyValues; -}; - - -const computeAverageFailureRate = (data: number[]): number => { - if (data.length === 0) return 0; - const sum = data.reduce((acc, val) => acc + val, 0); - return sum / data.length; - }; - - -interface ChartGridProps { - data: NodeMetrics[] - } - - export const ChartGrid: React.FC = ({ data }) => { - const [processedData, setProcessedData] = useState([]); - const [isLoading, setIsLoading] = useState(true); - - React.useEffect(() => { - const processData = () => { - const groupedItems = groupBy(data, 'node_id'); - - const processed = Object.keys(groupedItems).map(nodeId => { - const items = groupedItems[nodeId]; - const dailyData = calculateDailyValues(items); - - return { - nodeId, - title: nodeId.split('-')[0], - subnetId: items[0].subnet_id, - dailyData: dailyData, - failureRateSum: dailyData.reduce((sum, item) => sum + item.failureRate, 0), - failureRateAvg: computeAverageFailureRate(dailyData.map(elem => elem.failureRate)), - }; - }).sort((a, b) => b.failureRateSum - a.failureRateSum); - - setProcessedData(processed); - setIsLoading(false); - }; - - processData(); - }, [data]); - - return ( - - {isLoading ? ( - - - - ) : ( - processedData.slice(0, 10).map(({ nodeId, title, subnetId, dailyData, failureRateAvg }, index) => ( - - - - - - - {nodeId} - - - - - - - - new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }).replace(" ", "\n") }]} - series={[ - { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, - ]} - dataset={dailyData} - height={400} - /> - - - - - - - )) - )} - - ); -}; -interface StackedChartProps { - data: NodeMetrics[]; - name: string | null; - } - - export const StackedChart: React.FC = ({ data, name }) => { - const [stackOrder, setStackOrder] = useState('ascending'); - const [isLoading, setIsLoading] = useState(true); - const [modifiedSeries, setModifiedSeries] = useState([]); - - React.useEffect(() => { - const processData = () => { - const nodesGrouped = groupBy(data, 'node_id'); - - const chartData = Object.keys(nodesGrouped).flatMap(nodeId => { - const items = nodesGrouped[nodeId]; - const dailyData = calculateDailyValues(items); - return { - data: dailyData.map(daily => daily.failureRate), - stack: 'A', - label: nodeId, - }; - }); - - const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; - - setModifiedSeries(series); - setIsLoading(false); - }; - - processData(); - }, [data, stackOrder]); - - return ( - - - - - - Subnet: {name} - - - - - - {isLoading ? ( - - - - ) : ( - - - `${value}%`, - label: 'Sum nodes failure rate', - }, - ]} - sx={{ - p: 2, - [`.${axisClasses.left} .${axisClasses.label}`]: { - transform: 'translateX(-35px)', - }, - }} - borderRadius={9} - series={modifiedSeries} - height={800} - /> - - - )} - - - - ); -}; - - export const TestChart: React.FC = ({ data, name }) => { - - return ( - - - - - - Subnet: {name} - - - - - - - - ); - }; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx index 7c12c92e8..8584f318c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx @@ -2,121 +2,82 @@ import React from 'react'; import { Drawer as MUIDrawer, List, - Typography, - MenuItem, - Theme, - Accordion, - AccordionSummary, - AccordionDetails, - FormControl, - InputLabel, - Select, - ListItem, + ListItemButton, + ListItemText, + Collapse, IconButton, + ListItem, Toolbar, - Button, - ListItemButton, } from '@mui/material'; import { Link } from 'react-router-dom'; -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import { Filters } from './FilterBar'; -import { SxProps } from '@mui/system'; import Logo from '../assets/icp_logo.svg'; +import { ExpandLess, ExpandMore } from '@mui/icons-material'; interface DrawerProps { subnets: Set; nodeProviders: Set; drawerWidth: number; - theme: Theme; - setFilters: React.Dispatch>; } -const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth, theme, setFilters }) => { +const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth }) => { + const [openSubnets, setOpenSubnets] = React.useState(false); + const [openNP, setOpenNp] = React.useState(false); - const handleSubnetSelect = (subnet: string) => { - setFilters((prev) => ({ ...prev, subnet, nodeProvider: null })); - }; - - const handleNodeProviderSelect = (nodeProvider: string) => { - setFilters((prev) => ({ ...prev, nodeProvider, subnet: null })); - }; + const renderCollapsibleList = ( + title: string, + items: Set, + open: boolean, + setOpen: React.Dispatch>, + basePath: string + ) => ( + <> + setOpen(!open)}> + + {open ? : } + + + + {Array.from(items).map((item, index) => ( + + + + + + ))} + + + + ); return ( - + - - Logo - + + Logo + - - - - - - - - } - aria-controls="panel1a-content" - id="panel1a-header" - > - Subnets - - - - - - {Array.from(subnets).map((subnet, index) => ( - - - handleSubnetSelect(subnet)}> - {subnet.toString().split("-")[0]} - - - - ))} - - - - - - } - aria-controls="panel1a-content" - id="panel1a-header" - > - Node Providers - - - - {Array.from(nodeProviders).map((nodeProvider, index) => ( - handleNodeProviderSelect(nodeProvider)}> - - {nodeProvider.toString().split("-")[0]} - - - ))} - - - - + {renderCollapsibleList("Subnets", subnets, openSubnets, setOpenSubnets, "subnets")} + {renderCollapsibleList("Node Providers", nodeProviders, openNP, setOpenNp, "node-providers")} + ); }; export default Drawer; - - diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx index 71ad6fc9a..fa9702bc3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx @@ -1,21 +1,18 @@ -import React, { useState, useEffect, ChangeEvent } from 'react'; -import { AppBar, Toolbar, TextField, Box, MenuItem, Select, InputLabel, FormControl, SelectChangeEvent } from '@mui/material'; +import React from 'react'; +import { Toolbar } from '@mui/material'; import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -import { Principal } from '@dfinity/principal'; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; // Define the types for props -export interface Filters { +export interface PeriodFilter { dateStart: Date; dateEnd: Date; - subnet: string | null; - nodeProvider: string | null; } interface FilterBarProps { - filters: Filters; - setFilters: React.Dispatch>; + filters: PeriodFilter; + setFilters: React.Dispatch>; subnets: Set | null; // Use string instead of String } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx new file mode 100644 index 000000000..75478008b --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx @@ -0,0 +1,63 @@ +import { Box, Typography } from '@mui/material'; +import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; +import React from 'react'; + +export default function FailureRateArc(value: number) { + return ( + + + Failure Rate + + `${value}%` + } + sx={(theme) => ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 20, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#FF6347', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> + + ); +} + +export function RewardsArc(value: number) { + return ( + + + Node Reward + + `${value}%` + } + sx={(theme) => ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 20, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> + + ); +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx index ef250fa9c..1753db077 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx @@ -1,6 +1,7 @@ -import { AppBar, Toolbar, Typography, IconButton, styled } from '@mui/material'; +import { Toolbar, Typography, styled } from '@mui/material'; +import React from 'react'; -const Title = styled(Typography)(({ theme }) => ({ +const Title = styled(Typography)(() => ({ flexGrow: 1, fontWeight: 500, fontSize: '1.5rem', @@ -12,10 +13,9 @@ const Title = styled(Typography)(({ theme }) => ({ const Header = () => { return ( - - Nodes Penalties + Node Rewards ); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx new file mode 100644 index 000000000..3cc1efaf2 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -0,0 +1,101 @@ +import React, { useState } from 'react'; +import { Box, Grid, Paper, Stack, Typography, Autocomplete, TextField } from '@mui/material'; +import { axisClasses, BarChart } from '@mui/x-charts'; +import { DashboardNodeMetrics } from '../models/NodeMetrics'; +import { styled } from '@mui/material/styles'; +import Divider from '@mui/material/Divider'; +import { PeriodFilter } from './FilterBar'; +import { getFormattedDates, transformDailyData } from '../utils/utils'; +import FailureRateArc, { RewardsArc } from './Gauge'; + +export const Root = styled('div')(({ theme }) => ({ + width: '100%', + ...theme.typography.body2, + color: theme.palette.text.secondary, + '& > :not(style) ~ :not(style)': { + marginTop: theme.spacing(2), + }, +})); + +export interface NodeListProps { + dashboardNodeMetrics: DashboardNodeMetrics[], + periodFilter: PeriodFilter +} + +export const NodeList: React.FC = ({ dashboardNodeMetrics, periodFilter }) => { + const [filteredMetrics, setFilteredMetrics] = useState(dashboardNodeMetrics); + + const handleSearchChange = (event: unknown, value: string | null) => { + if (value) { + const filtered = dashboardNodeMetrics.filter(node => node.nodeId.includes(value)); + setFilteredMetrics(filtered); + } else { + setFilteredMetrics(dashboardNodeMetrics); + } + }; + + return ( + + + + node.nodeId)} + onInputChange={handleSearchChange} + renderInput={(params) => ( + + )} + /> + + {filteredMetrics.slice(0, 10).map(({ nodeId, dailyData, failureRateAvg }, index) => ( + + + + {nodeId} + + + + + + + `${value}%`, + label: 'Failure Rate', + min: 0, + max: 100, + }, + ]} + series={[ + { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, + ]} + dataset={transformDailyData(dailyData)} + height={400} + /> + + + {FailureRateArc(Math.round(failureRateAvg))} + {RewardsArc(Math.round(failureRateAvg))} + + + + + ))} + + + ); +}; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx new file mode 100644 index 000000000..7be98b0d9 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx @@ -0,0 +1,47 @@ +import * as React from 'react'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TableRow from '@mui/material/TableRow'; +import Paper from '@mui/material/Paper'; +import { DashboardNodeMetrics } from '../models/NodeMetrics'; +import { SxProps, Theme } from '@mui/material'; + +interface RewardTableProps { + dashboardNodeMetrics: DashboardNodeMetrics[], + sx?: SxProps; + } + +const RewardTable: React.FC = ({ dashboardNodeMetrics }) => { + return ( + + + + + Nodes + Failure Rates Avg. + + + + {dashboardNodeMetrics.map((nodeMetrics) => ( + + + {nodeMetrics.nodeId} + + + {Math.round(nodeMetrics.failureRateAvg)}% + + + ))} + +
+
+ ); +} + +export default RewardTable; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx new file mode 100644 index 000000000..3b2f193aa --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -0,0 +1,72 @@ +import React, { useState } from 'react'; +import { Box, Paper, Typography } from '@mui/material'; +import { axisClasses, BarChart, StackOrderType } from '@mui/x-charts'; +import Divider from '@mui/material/Divider'; +import { useParams } from 'react-router-dom'; +import { getFormattedDates } from '../utils/utils'; +import { ChartsNoDataOverlay } from '@mui/x-charts/ChartsOverlay'; +import RewardTable from './RewardTable'; +import { DashboardNodeMetrics } from '../models/NodeMetrics'; +import { PeriodFilter } from './FilterBar'; +import { Root } from './NodeList'; + +export interface SubnetChartProps { + dashboardNodeMetrics: DashboardNodeMetrics[], + periodFilter: PeriodFilter + } + +export const SubnetChart: React.FC = ({ dashboardNodeMetrics, periodFilter }) => { + const [stackOrder] = useState('ascending'); + const { subnet } = useParams(); + const subnetNodeMetrics = dashboardNodeMetrics + .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnetId === subnet)) + const chartData = subnetNodeMetrics + .filter((nodeMetrics) => nodeMetrics.dailyData.some(fr => fr.failureRate >= 10)) + .map((nodeMetrics) => nodeMetrics.getChartSeries()); + const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; + + return ( + + + + + Subnet: {subnet} + + + + + Daily Failure Rate + {chartData.length > 0 ? ( + `${value}%`, + label: 'Failure Rate', + min: 0, + max: 100, + }, + ]} + sx={{ + p: 2, + [`.${axisClasses.left} .${axisClasses.label}`]: { + transform: 'translateX(-25px)', + }, + }} + borderRadius={9} + series={series} + height={500} + />) : ()} + + + + + + + + ); +}; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx index 2798390c4..e6fc59266 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -1,23 +1,81 @@ import { Principal } from '@dfinity/principal'; +import { computeAverageFailureRate } from '../utils/utils'; export class NodeMetrics { date: Date; - num_block_failures_total: bigint; - node_id: Principal; - num_blocks_proposed_total: bigint; - subnet_id: Principal; + numBlockFailuresTotal: bigint; + nodeId: Principal; + numBlocksProposedTotal: bigint; + subnetId: Principal constructor( ts: bigint, - num_block_failures_total: bigint, - node_id: Principal, - num_blocks_proposed_total: bigint, - subnet_id: Principal + numBlockFailuresTotal: bigint, + nodeId: Principal, + numBlocksProposedTotal: bigint, + subnetId: Principal ) { this.date = new Date(Number(ts / BigInt(1e6))); - this.num_block_failures_total = num_block_failures_total; - this.node_id = node_id; - this.num_blocks_proposed_total = num_blocks_proposed_total; - this.subnet_id = subnet_id; + this.numBlockFailuresTotal = numBlockFailuresTotal; + this.nodeId = nodeId; + this.numBlocksProposedTotal = numBlocksProposedTotal; + this.subnetId = subnetId; + } +} + +export class DailyData { + date: Date; + subnetId: string; + numBlockFailures: number; + numBlocksProposed: number; + failureRate: number; + + constructor( + date: Date, + subnetId: string, + numBlockFailures: number, + numBlocksProposed: number + ) { + this.date = date; + this.subnetId = subnetId; + this.numBlockFailures = numBlockFailures; + this.numBlocksProposed = numBlocksProposed; + this.failureRate = numBlockFailures / (numBlockFailures + numBlocksProposed) * 100; + } + + public transformDailyData(data: DailyData[]): { [key: string]: string | number | Date | null | undefined }[] { + return data.map(item => ({ + date: item.date, + subnetId: item.subnetId, + numBlockFailures: item.numBlockFailures, + numBlocksProposed: item.numBlocksProposed, + failureRate: item.failureRate, + })); + } +} + +export class DashboardNodeMetrics { + nodeId: string; + nodeIdSmall: string; + dailyData: DailyData[]; + failureRateSum: number; + failureRateAvg: number; + + constructor( + nodeId: string, + dailyData: DailyData[] + ) { + this.nodeId = nodeId; + this.nodeIdSmall = nodeId.split('-')[0]; + this.dailyData = dailyData; + this.failureRateSum = dailyData.reduce((sum, item) => sum + item.failureRate, 0); + this.failureRateAvg = computeAverageFailureRate(dailyData.map(elem => elem.failureRate)); + } + + public getChartSeries() { + return { + data: this.dailyData.map(daily => daily.failureRate), + label: this.nodeId, + }; } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx new file mode 100644 index 000000000..5fa4c5a85 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -0,0 +1,78 @@ +import { PeriodFilter } from "../components/FilterBar"; +import { DailyData, NodeMetrics } from "../models/NodeMetrics"; + +export const getFormattedDates = (period: PeriodFilter): string[] => { + const { dateStart, dateEnd } = period; + const dates: string[] = []; + const currentDate = new Date(dateStart); + + while (currentDate <= dateEnd) { + dates.push( + currentDate.toLocaleDateString('UTC', { month: 'short', day: 'numeric' }).replace(" ", "\n") + ); + currentDate.setDate(currentDate.getDate() + 1); + } + + return dates; + }; + +export function transformDailyData(data: DailyData[]): { [key: string]: string | number | Date | null | undefined }[] { + return data.map(item => ({ + date: item.date, + subnetId: item.subnetId, + numBlockFailures: item.numBlockFailures, + numBlocksProposed: item.numBlocksProposed, + failureRate: item.failureRate, + })); + } + +export function groupBy(items: T[], key: K): Record { + return items.reduce((result, item) => { + const groupKey = String(item[key]); + if (!result[groupKey]) { + result[groupKey] = []; + } + result[groupKey].push(item); + return result; + }, {} as Record); + } + + + export function calculateDailyValues (items: NodeMetrics[],): DailyData[] { + const dailyValues: DailyData[] = []; + let previousTotals = { failures: 0.0, proposed: 0.0 }; + + items.sort((a, b) => a.date.getTime() - b.date.getTime()); + + for (const item of items) { + const currentDate = item.date; + const currentSubnet = item.subnetId; + const currentTotals = { + failures: Number(item.numBlockFailuresTotal), + proposed: Number(item.numBlocksProposedTotal), + }; + + if (previousTotals.failures || previousTotals.proposed) { + const dailyFailures = currentTotals.failures - previousTotals.failures; + const dailyProposed = currentTotals.proposed - previousTotals.proposed; + + dailyValues.push( new DailyData( + currentDate, + currentSubnet.toText(), + dailyFailures, + dailyProposed, + )); + } + + previousTotals = currentTotals; + } + + return dailyValues; + } + + export const computeAverageFailureRate = (data: number[]): number => { + if (data.length === 0) return 0; + const sum = data.reduce((acc, val) => acc + val, 0); + return sum / data.length; + }; + From b78eff675b903b7b1fec317a7c144bad3a1926ad Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 31 Jul 2024 10:31:24 +0200 Subject: [PATCH 06/40] Adjust scale --- .../src/App.tsx | 70 ++++++------ .../src/components/Gauge.tsx | 16 +-- .../src/components/NodeList.tsx | 100 ++++++++++-------- 3 files changed, 101 insertions(+), 85 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index 1a83175c4..faf9307df 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -1,9 +1,9 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; import FilterBar, { PeriodFilter } from './components/FilterBar'; import Drawer from './components/Drawer'; import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; -import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; // Adjust the path as needed +import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; import { DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; import { NodeList } from './components/NodeList'; @@ -39,8 +39,8 @@ function App() { dateStart: thirtyDaysAgo, dateEnd: new Date() }); - const [nodeMetrics, setNodeMetrics] = useState([]); - const [subnets, setSubnets] = useState>(new Set()); + const [nodeMetrics, setnodeMetrics] = useState([]); + let subnets: Set = new Set(); const [nodeProviders, setNodeProviders] = useState>(new Set()); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(""); @@ -49,7 +49,6 @@ function App() { useEffect(() => { const fetchNodes = async () => { try { - setIsLoading(true); const request: SubnetNodeMetricsArgs = { ts: [], subnet_id: [], @@ -70,39 +69,46 @@ function App() { ); }) }); - const metricsInPeriod = metrics.filter((metrics) => { - const metricsDate = metrics.date; - const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; - return isDateInRange; - }); - - const subnets: Set = new Set(metrics.map(metric => metric.subnetId.toText())); - const grouped = groupBy(metricsInPeriod, 'nodeId'); - const groupedMetrics = Object.keys(grouped).map(nodeId => { - const items = grouped[nodeId]; - const dailyData = calculateDailyValues(items); - - return new DashboardNodeMetrics( - nodeId, - dailyData, - ); - }) - .sort((a, b) => b.failureRateAvg - a.failureRateAvg); - - setNodeMetrics(groupedMetrics); - setSubnets(subnets); - setIsLoading(false); + setnodeMetrics(metrics); } else { setError(response.Err); } } catch (error) { console.error("Error fetching nodes:", error); + } finally { + setIsLoading(false); } }; fetchNodes(); - }, [periodFilter]); + }, []); + + + const dashboardNodeMetrics = useMemo(() => { + const metricsInPeriod = nodeMetrics.filter((metrics) => { + const metricsDate = metrics.date; + const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; + return isDateInRange; + }); + + subnets = new Set(nodeMetrics.map(metric => metric.subnetId.toText())); + + const grouped = groupBy(metricsInPeriod, 'nodeId'); + const groupedMetrics = Object.keys(grouped).map(nodeId => { + const items = grouped[nodeId]; + const dailyData = calculateDailyValues(items); + + return new DashboardNodeMetrics( + nodeId, + dailyData, + ); + }) + .sort((a, b) => b.failureRateAvg - a.failureRateAvg); + + return groupedMetrics + }, [periodFilter, nodeMetrics]); + if (error) { return
Error: {error}
; @@ -131,12 +137,14 @@ function App() { /> - } /> + ) : ()} + /> ) : ()} + isLoading ? () : ()} /> ) : ()} + isLoading ? () : ()} /> diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx index 75478008b..55604e846 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx @@ -5,12 +5,12 @@ import React from 'react'; export default function FailureRateArc(value: number) { return ( - + Failure Rate ({ [`& .${gaugeClasses.valueText}`]: { - fontSize: 20, + fontSize: 15, }, [`& .${gaugeClasses.valueArc}`]: { fill: '#FF6347', @@ -35,12 +35,12 @@ export default function FailureRateArc(value: number) { export function RewardsArc(value: number) { return ( - + Node Reward ({ [`& .${gaugeClasses.valueText}`]: { - fontSize: 20, + fontSize: 15, }, [`& .${gaugeClasses.valueArc}`]: { fill: '#52b202', diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index 3cc1efaf2..a8fa2a683 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { Box, Grid, Paper, Stack, Typography, Autocomplete, TextField } from '@mui/material'; import { axisClasses, BarChart } from '@mui/x-charts'; -import { DashboardNodeMetrics } from '../models/NodeMetrics'; +import { DailyData, DashboardNodeMetrics } from '../models/NodeMetrics'; import { styled } from '@mui/material/styles'; import Divider from '@mui/material/Divider'; import { PeriodFilter } from './FilterBar'; @@ -22,9 +22,57 @@ export interface NodeListProps { periodFilter: PeriodFilter } +function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: number, periodFilter: PeriodFilter): React.ReactNode { + return ( + + + + {nodeId} + + + {FailureRateArc(Math.round(failureRateAvg))} + {RewardsArc(Math.round(failureRateAvg))} + + + + + `${value}%`, + label: 'Failure Rate', + min: 0, + max: 100, + }, + ]} + series={[ + { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, + ]} + dataset={transformDailyData(dailyData)} + height={400} + /> + + + ) +} + export const NodeList: React.FC = ({ dashboardNodeMetrics, periodFilter }) => { const [filteredMetrics, setFilteredMetrics] = useState(dashboardNodeMetrics); + console.info(dashboardNodeMetrics.length) + const handleSearchChange = (event: unknown, value: string | null) => { if (value) { const filtered = dashboardNodeMetrics.filter(node => node.nodeId.includes(value)); @@ -48,53 +96,13 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period )} /> + {filteredMetrics.slice(0, 10).map(({ nodeId, dailyData, failureRateAvg }, index) => ( - - - - {nodeId} - - - - - - - `${value}%`, - label: 'Failure Rate', - min: 0, - max: 100, - }, - ]} - series={[ - { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, - ]} - dataset={transformDailyData(dailyData)} - height={400} - /> - - - {FailureRateArc(Math.round(failureRateAvg))} - {RewardsArc(Math.round(failureRateAvg))} - - - - + + {renderChart(nodeId, dailyData, failureRateAvg, periodFilter)} + ))} + ); From 84e91ab391f96dbc7bb8788b7443ab635f3893c5 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 31 Jul 2024 10:39:41 +0200 Subject: [PATCH 07/40] Add 3 spacing --- .../src/components/NodeList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index a8fa2a683..217cfde67 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -97,8 +97,8 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period /> - {filteredMetrics.slice(0, 10).map(({ nodeId, dailyData, failureRateAvg }, index) => ( - + {filteredMetrics.slice(0, 20).map(({ nodeId, dailyData, failureRateAvg }, index) => ( + {renderChart(nodeId, dailyData, failureRateAvg, periodFilter)} ))} From 6e7515ebd7dde199d78af6bcb9d1b9aa84db1e75 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 31 Jul 2024 11:06:11 +0200 Subject: [PATCH 08/40] 2 nodes per row in NodeList --- .../src/components/NodeList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index 217cfde67..66fe0eee9 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -98,7 +98,7 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period {filteredMetrics.slice(0, 20).map(({ nodeId, dailyData, failureRateAvg }, index) => ( - + {renderChart(nodeId, dailyData, failureRateAvg, periodFilter)} ))} From 558b6c0bbbc26444de61b305b086be76a503facc Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 31 Jul 2024 11:09:28 +0200 Subject: [PATCH 09/40] Remove added interface --- .../src/trustworthy-node-metrics-frontend/src/App.tsx | 2 +- .../src/trustworthy-node-metrics/src/lib.rs | 9 --------- .../src/trustworthy-node-metrics/src/stable_memory.rs | 7 ------- .../trustworthy-node-metrics.did | 1 - 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index faf9307df..a01f05e4e 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect, useMemo } from 'react'; import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; import FilterBar, { PeriodFilter } from './components/FilterBar'; import Drawer from './components/Drawer'; -import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; +import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; import { DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 1c7fe7c11..557c34c05 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -59,12 +59,3 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { - let nodes = stable_memory::get_nodes(); - ic_cdk::println!("Fetched {} nodes for frontend", nodes.len()); - - nodes -} - diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 45430a56f..e93e6edb4 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -36,10 +36,3 @@ pub fn latest_key() -> Option { pub fn get_metrics(ts: TimestampNanos) -> Vec<(TimestampNanos, Vec)> { MAP.with(|p| p.borrow().range(ts..).map(|(ts, storable)| (ts, storable.0)).collect_vec()) } - -pub fn get_nodes() -> Vec { - MAP.with(|p| p.borrow().iter().collect_vec()) - .into_iter().flat_map(|(_, storable)| { - storable.0.into_iter().map(|s| s.node_metrics.into_iter().map(|n| n.node_id.to_string()).collect_vec()) - }).flatten().collect_vec() -} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index f5fdaa2e1..5440edd0d 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -24,5 +24,4 @@ type SubnetNodeMetricsArgs = record { service : { "subnet_node_metrics" : (SubnetNodeMetricsArgs) -> (SubnetNodeMetricsResult) query; - "get_nodes" : () -> (vec text) query; } From 8b0774abebdab0450c05ca7490edc79fcfed86f2 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 31 Jul 2024 11:19:27 +0200 Subject: [PATCH 10/40] Change title --- .../src/trustworthy-node-metrics-frontend/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html index 867e95ea5..c1d49e2de 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html @@ -4,7 +4,7 @@ - IC Hello Starter + Node Rewards App From c3ed7b81633b29f3e6f2860f93585d6812e10542 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 31 Jul 2024 14:09:33 +0200 Subject: [PATCH 11/40] Remove side effectss --- .../src/App.tsx | 2 - .../src/components/NodeList.tsx | 74 +++++++++++-------- .../src/components/SubnetChart.tsx | 9 ++- .../src/models/NodeMetrics.tsx | 15 ++-- .../src/utils/utils.tsx | 27 ++++++- 5 files changed, 81 insertions(+), 46 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index a01f05e4e..e0680f966 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -55,8 +55,6 @@ function App() { }; const response: SubnetNodeMetricsResult = await trustworthy_node_metrics.subnet_node_metrics(request); - console.info("Got response", response); - if ('Ok' in response) { const metrics: NodeMetrics[] = response.Ok.flatMap((metricResponse) => { return metricResponse.node_metrics.map((nodeMetrics) => { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index 66fe0eee9..6cbc7ab0c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react'; import { Box, Grid, Paper, Stack, Typography, Autocomplete, TextField } from '@mui/material'; import { axisClasses, BarChart } from '@mui/x-charts'; -import { DailyData, DashboardNodeMetrics } from '../models/NodeMetrics'; +import { ChartData, DailyData, DashboardNodeMetrics } from '../models/NodeMetrics'; import { styled } from '@mui/material/styles'; import Divider from '@mui/material/Divider'; import { PeriodFilter } from './FilterBar'; -import { getFormattedDates, transformDailyData } from '../utils/utils'; +import { generateChartData, getFormattedDates, transformDailyData } from '../utils/utils'; import FailureRateArc, { RewardsArc } from './Gauge'; export const Root = styled('div')(({ theme }) => ({ @@ -23,6 +23,9 @@ export interface NodeListProps { } function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: number, periodFilter: PeriodFilter): React.ReactNode { + + const chartDailyData: ChartData[] = generateChartData(periodFilter, dailyData); + return ( @@ -37,41 +40,50 @@ function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: num `${value}%`, - label: 'Failure Rate', - min: 0, - max: 100, - }, - ]} - series={[ - { dataKey: 'failureRate', label: "Failure Rate (%)", color: '#FF6347' }, - ]} - dataset={transformDailyData(dailyData)} - height={400} - /> + borderRadius={9} + sx={{ + p: 2, + [`.${axisClasses.left} .${axisClasses.label}`]: { + transform: 'translateX(-25px)', + }, + }} + slotProps={{ legend: { hidden: true } }} + xAxis={[{ + scaleType: 'band', + dataKey: 'date', + valueFormatter: (value: Date) => value.toLocaleDateString('UTC', { month: 'short', day: 'numeric' }).replace(" ", "\n") + }]} + yAxis={[ + { + valueFormatter: value => `${value}%`, + min: 0, + max: 100, + }, + ]} + series={[ + { dataKey: 'failureRate', label: "Failure Rate", color: '#FF6347', + valueFormatter: (value: number | null) => value ? `${value}%` : 'Not assigned' }, + ]} + dataset={chartDailyData.map(entry => ({ + date: entry.date, + failureRate: entry.failureRate, + }))} + + height={400} + /> ) } export const NodeList: React.FC = ({ dashboardNodeMetrics, periodFilter }) => { - const [filteredMetrics, setFilteredMetrics] = useState(dashboardNodeMetrics); + const [prevItems, setPrevItems] = useState(dashboardNodeMetrics); + const [filteredMetrics, setFilteredMetrics] = useState(prevItems); - console.info(dashboardNodeMetrics.length) + if (dashboardNodeMetrics !== prevItems) { + setPrevItems(dashboardNodeMetrics); + setFilteredMetrics(dashboardNodeMetrics) + } const handleSearchChange = (event: unknown, value: string | null) => { if (value) { @@ -97,7 +109,7 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period /> - {filteredMetrics.slice(0, 20).map(({ nodeId, dailyData, failureRateAvg }, index) => ( + {filteredMetrics.slice(0, 10).map(({ nodeId, dailyData, failureRateAvg }, index) => ( {renderChart(nodeId, dailyData, failureRateAvg, periodFilter)} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx index 3b2f193aa..8dd840a6e 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -3,7 +3,7 @@ import { Box, Paper, Typography } from '@mui/material'; import { axisClasses, BarChart, StackOrderType } from '@mui/x-charts'; import Divider from '@mui/material/Divider'; import { useParams } from 'react-router-dom'; -import { getFormattedDates } from '../utils/utils'; +import { generateChartData, getFormattedDates } from '../utils/utils'; import { ChartsNoDataOverlay } from '@mui/x-charts/ChartsOverlay'; import RewardTable from './RewardTable'; import { DashboardNodeMetrics } from '../models/NodeMetrics'; @@ -22,7 +22,12 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnetId === subnet)) const chartData = subnetNodeMetrics .filter((nodeMetrics) => nodeMetrics.dailyData.some(fr => fr.failureRate >= 10)) - .map((nodeMetrics) => nodeMetrics.getChartSeries()); + .map(nodeMetrics => { + return { + data: generateChartData(periodFilter, nodeMetrics.dailyData).map(daily => daily.failureRate), + label: nodeMetrics.nodeId, + } + }); const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; return ( diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx index e6fc59266..5ed69aaa3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -23,6 +23,11 @@ export class NodeMetrics { } } +export interface ChartData { + date: Date ; + failureRate: number | null; +} + export class DailyData { date: Date; subnetId: string; @@ -42,16 +47,6 @@ export class DailyData { this.numBlocksProposed = numBlocksProposed; this.failureRate = numBlockFailures / (numBlockFailures + numBlocksProposed) * 100; } - - public transformDailyData(data: DailyData[]): { [key: string]: string | number | Date | null | undefined }[] { - return data.map(item => ({ - date: item.date, - subnetId: item.subnetId, - numBlockFailures: item.numBlockFailures, - numBlocksProposed: item.numBlocksProposed, - failureRate: item.failureRate, - })); - } } export class DashboardNodeMetrics { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx index 5fa4c5a85..08e3252e8 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -1,5 +1,30 @@ import { PeriodFilter } from "../components/FilterBar"; -import { DailyData, NodeMetrics } from "../models/NodeMetrics"; +import { ChartData, DailyData, NodeMetrics } from "../models/NodeMetrics"; + +export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyData[]): ChartData[] => { + const { dateStart, dateEnd } = periodFilter; + const chartData: ChartData[] = []; + + const currentDate = new Date(dateStart); + + while (currentDate <= dateEnd) { + const dailyDataEntry = dailyData.find(data => + data.date.getFullYear() === currentDate.getFullYear() && + data.date.getMonth() === currentDate.getMonth() && + data.date.getDate() === currentDate.getDate() + ); + + chartData.push({ + date: new Date(currentDate), + failureRate: dailyDataEntry ? dailyDataEntry.failureRate : null, + }); + + currentDate.setDate(currentDate.getDate() + 1); + } + + return chartData; +}; + export const getFormattedDates = (period: PeriodFilter): string[] => { const { dateStart, dateEnd } = period; From 1d7654166d82121b69c16014292e8a12e5478382 Mon Sep 17 00:00:00 2001 From: Pietro Date: Fri, 2 Aug 2024 16:52:09 +0200 Subject: [PATCH 12/40] Add rewards computation --- .../trustworthy-node-metrics/args-rewards.bin | 5 + .../trustworthy-node-metrics/args.bin | 2 +- .../canister_ids.json | 3 + rs/dre-canisters/trustworthy-node-metrics/out | 2488 +++++++++++++++++ .../trustworthy-node-metrics/out-candid | 5 + .../trustworthy-node-metrics/pool_logs.sh | 1 + .../src/trustworthy-node-metrics/src/lib.rs | 42 +- .../src/rewards_manager.rs | 113 + .../src/stable_memory.rs | 44 +- .../src/trustworthy-node-metrics/src/types.rs | 26 +- .../trustworthy-node-metrics.did | 15 + 11 files changed, 2736 insertions(+), 8 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin create mode 100644 rs/dre-canisters/trustworthy-node-metrics/out create mode 100644 rs/dre-canisters/trustworthy-node-metrics/out-candid create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs diff --git a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin new file mode 100644 index 000000000..17f73611c --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin @@ -0,0 +1,5 @@ +(record { + from_ts = 1717372799135371824; + to_ts = 1720655999188798300; + nodes = vec { principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"}; +}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/args.bin index 32da99f14..d02ee1fb9 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/args.bin +++ b/rs/dre-canisters/trustworthy-node-metrics/args.bin @@ -1,4 +1,4 @@ (record { subnet_id = opt principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; - ts = opt 1720742398550724680; + ts = opt 0; }) diff --git a/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json b/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json index 801c55b3c..8b3cbe450 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json +++ b/rs/dre-canisters/trustworthy-node-metrics/canister_ids.json @@ -1,5 +1,8 @@ { "trustworthy-node-metrics": { "ic": "oqi72-gaaaa-aaaam-ac2pq-cai" + }, + "trustworthy-node-metrics-test": { + "ic": "ogyxv-7qaaa-aaaam-ac5ra-cai" } } \ No newline at end of file diff --git a/rs/dre-canisters/trustworthy-node-metrics/out b/rs/dre-canisters/trustworthy-node-metrics/out new file mode 100644 index 000000000..11fc02b2c --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/out @@ -0,0 +1,2488 @@ +{ + "Ok": [ + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2091791" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2093233" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2092456" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "50", + "num_blocks_proposed_total": "2092132" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2090761" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2091793" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1716681599483489334" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2104506" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2106115" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2105451" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "50", + "num_blocks_proposed_total": "2105005" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2103618" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2104698" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1716767999773366328" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2117379" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2118951" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2118512" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "50", + "num_blocks_proposed_total": "2117762" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2116431" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2117567" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1716854399060606686" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2130196" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2131848" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2131353" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "50", + "num_blocks_proposed_total": "2130602" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2129240" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2130592" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1716940799761899833" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2143138" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2144621" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2144270" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "50", + "num_blocks_proposed_total": "2143502" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2142135" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2143370" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717027199691163351" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2156081" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2157434" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2156993" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2156320" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2155090" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2156131" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717113599414303587" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2168956" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2170473" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2169884" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2169061" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2167860" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2169020" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717199999631964702" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2181963" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2183390" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2182612" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2182026" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2180755" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2181713" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717286399752468497" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2194888" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2196326" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2195633" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2194709" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2193565" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2194546" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717372799135371824" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2208031" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2209148" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2208500" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2207473" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2206320" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2207389" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717459199927811941" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2220906" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2221973" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2221423" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2220255" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2219268" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2220227" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717545599429653929" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2233757" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2234665" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2234215" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2233088" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2232354" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2233137" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717631999111347594" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2246535" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2247410" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2247092" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2245910" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2245259" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2246060" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717718399425821175" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2259389" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2260082" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2259931" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2258805" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2258092" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2259019" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717804799314913257" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2272404" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2273036" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2272642" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2271797" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2270720" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2271966" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717891199670774838" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2285168" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2285903" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2285593" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2284784" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2283405" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2284963" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1717977599988572190" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2298201" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2298917" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2298277" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2297466" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2296433" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2297771" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718063999910970656" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2310962" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2311772" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2311244" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2310375" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2309307" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2310650" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718150399585179614" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2323790" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2324562" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "34", + "num_blocks_proposed_total": "2324105" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "53", + "num_blocks_proposed_total": "2323278" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2322155" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2323669" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718236799815720400" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "49", + "num_blocks_proposed_total": "2336425" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "63", + "num_blocks_proposed_total": "2337408" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "36", + "num_blocks_proposed_total": "2336847" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2336103" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "56", + "num_blocks_proposed_total": "2334941" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2336333" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718323199240586165" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "54", + "num_blocks_proposed_total": "2349232" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2350231" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "36", + "num_blocks_proposed_total": "2349796" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2349105" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2347711" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2349063" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718409598936710240" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "54", + "num_blocks_proposed_total": "2362069" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2362966" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "36", + "num_blocks_proposed_total": "2362641" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2362222" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2360675" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2361880" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718495999375227452" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "54", + "num_blocks_proposed_total": "2374694" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2375949" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "36", + "num_blocks_proposed_total": "2375490" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2375136" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "61", + "num_blocks_proposed_total": "2373648" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2374846" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718582399154761330" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2387359" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2388857" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "39", + "num_blocks_proposed_total": "2388280" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2387999" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2386501" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2387806" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718668799743445274" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2400042" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2401750" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "39", + "num_blocks_proposed_total": "2401175" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2400940" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2399542" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2400833" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718755199463039848" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "55", + "num_blocks_proposed_total": "2412859" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2414534" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "39", + "num_blocks_proposed_total": "2414166" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2413924" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2412394" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2413776" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718841599195423534" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "56", + "num_blocks_proposed_total": "2425576" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "66", + "num_blocks_proposed_total": "2427451" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2427066" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2426679" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2425293" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2426583" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1718927999351658313" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "56", + "num_blocks_proposed_total": "2438270" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "66", + "num_blocks_proposed_total": "2440320" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2440000" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2439523" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2438133" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2439508" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719014399075814558" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "56", + "num_blocks_proposed_total": "2451184" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "66", + "num_blocks_proposed_total": "2453089" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2452964" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2452341" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2450996" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2452359" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719100799337547664" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "56", + "num_blocks_proposed_total": "2464206" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "66", + "num_blocks_proposed_total": "2465769" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "40", + "num_blocks_proposed_total": "2465753" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2465285" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2463886" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2465131" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719187199352329068" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2477103" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "67", + "num_blocks_proposed_total": "2478616" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2478661" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2478184" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2476416" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2478016" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719273598957247659" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2490079" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "67", + "num_blocks_proposed_total": "2491390" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2491572" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2491071" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2489352" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2491012" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719359999862921420" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2502970" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "67", + "num_blocks_proposed_total": "2504411" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2504508" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2504095" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2502195" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "79", + "num_blocks_proposed_total": "2503739" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719446398888794692" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2515795" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2517158" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2517197" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2517198" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2514964" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2516556" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719532799564246555" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2528829" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2530145" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2530167" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2530012" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2527764" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2529455" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719619199478594702" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2541716" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2543046" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2542986" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2542949" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2540724" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2542452" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719705599706281335" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2554663" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2556212" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2555981" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2555636" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2553670" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2555219" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719791999572867905" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2567632" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2569148" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2568926" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2568522" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2566493" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2568174" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719878399164706522" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2580664" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2582096" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2581722" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2581207" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2579459" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2581221" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1719964799125355947" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "57", + "num_blocks_proposed_total": "2593560" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2594969" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "41", + "num_blocks_proposed_total": "2594570" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2594211" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "62", + "num_blocks_proposed_total": "2592368" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "81", + "num_blocks_proposed_total": "2594096" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720051199532858341" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2606365" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2607706" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2607463" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "73", + "num_blocks_proposed_total": "2606989" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2605254" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2606910" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720137599383958858" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2619247" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2620659" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2620250" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "73", + "num_blocks_proposed_total": "2619873" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2618242" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2619903" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720223999433044766" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2632286" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2633577" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2633156" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "73", + "num_blocks_proposed_total": "2632817" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2631087" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2632751" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720310399249378780" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2645143" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2646424" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2646204" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "73", + "num_blocks_proposed_total": "2645788" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2644044" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2645572" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720396799109521534" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2657997" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2659108" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2659434" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "73", + "num_blocks_proposed_total": "2658642" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2656929" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2658520" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720483199208014620" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2670868" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2671974" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "42", + "num_blocks_proposed_total": "2672452" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "73", + "num_blocks_proposed_total": "2671586" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2670106" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2671362" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720569599968661148" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2683633" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2684933" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "47", + "num_blocks_proposed_total": "2685432" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2684507" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "65", + "num_blocks_proposed_total": "2683016" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "82", + "num_blocks_proposed_total": "2684022" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720655999188798300" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2696354" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2697611" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2698223" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2697346" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2695826" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2696842" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720742399550724680" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2709293" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2710414" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2711105" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2710206" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2708581" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2709897" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720828799201145810" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2722224" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2723363" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2723856" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2722971" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2721557" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2722813" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1720915198910706388" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2735028" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2736195" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2736895" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2735910" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2734416" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2735627" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721001599683681697" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2747751" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2749350" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2749810" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2748745" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2747228" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2748482" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721087999904777181" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2760326" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2762401" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2762581" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2761716" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2760260" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2761358" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721174399251876961" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2773126" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "68", + "num_blocks_proposed_total": "2775106" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2775457" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2774511" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "70", + "num_blocks_proposed_total": "2772928" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2773914" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721260799590889198" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2786086" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2787961" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2788080" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2787168" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2785540" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2786754" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721347199749909168" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2799163" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2800615" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2801000" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2800072" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2798386" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2799669" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721433599883710941" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2812190" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2813377" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2813894" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2813043" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2811150" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2812592" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721519999560756953" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2825069" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2826308" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2826643" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2825851" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2824191" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2825528" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721606399618868422" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2837879" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2839288" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2839427" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2838783" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2837072" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2838242" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721692799708125439" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2850629" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2852125" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2852372" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2851618" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2849941" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2851119" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721779199416468524" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "58", + "num_blocks_proposed_total": "2863616" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2865056" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "51", + "num_blocks_proposed_total": "2865276" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2864484" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "71", + "num_blocks_proposed_total": "2862767" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2863979" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721865599927488258" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "59", + "num_blocks_proposed_total": "2876310" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2877878" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2878148" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "76", + "num_blocks_proposed_total": "2877301" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2875657" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2876962" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1721951998934090476" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "59", + "num_blocks_proposed_total": "2889213" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2890644" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2891059" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "76", + "num_blocks_proposed_total": "2890341" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2888586" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2889775" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722038399476499196" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "59", + "num_blocks_proposed_total": "2902008" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2903332" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2904042" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "76", + "num_blocks_proposed_total": "2903375" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2901529" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2902701" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722124799451395655" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "59", + "num_blocks_proposed_total": "2915083" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2916137" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2916814" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "76", + "num_blocks_proposed_total": "2916115" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2914515" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2915701" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722211199022265393" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "59", + "num_blocks_proposed_total": "2927845" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2928983" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2929756" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "76", + "num_blocks_proposed_total": "2929079" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2927495" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2928583" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722297598880602693" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "59", + "num_blocks_proposed_total": "2940696" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2942028" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2942647" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "76", + "num_blocks_proposed_total": "2941955" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "74", + "num_blocks_proposed_total": "2940187" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2941595" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722383999973967169" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "60", + "num_blocks_proposed_total": "2953418" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2954990" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2955425" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2954707" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2952988" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2954763" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722470399577446169" + }, + { + "node_metrics": [ + { + "node_id": "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe", + "num_block_failures_total": "60", + "num_blocks_proposed_total": "2966439" + }, + { + "node_id": "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe", + "num_block_failures_total": "69", + "num_blocks_proposed_total": "2967842" + }, + { + "node_id": "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae", + "num_block_failures_total": "52", + "num_blocks_proposed_total": "2968329" + }, + { + "node_id": "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae", + "num_block_failures_total": "77", + "num_blocks_proposed_total": "2967694" + }, + { + "node_id": "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae", + "num_block_failures_total": "75", + "num_blocks_proposed_total": "2965847" + }, + { + "node_id": "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe", + "num_block_failures_total": "83", + "num_blocks_proposed_total": "2967512" + } + ], + "subnet_id": "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe", + "ts": "1722556799604228415" + } + ] +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/out-candid b/rs/dre-canisters/trustworthy-node-metrics/out-candid new file mode 100644 index 000000000..380c990f1 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/out-candid @@ -0,0 +1,5 @@ +( + variant { + Ok = vec { record { ts = 1_720_742_399_550_724_680 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_696_354 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_697_611 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_698_223 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_697_346 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_695_826 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_696_842 : nat64;};};}; record { ts = 1_720_828_799_201_145_810 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_709_293 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_710_414 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_711_105 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_710_206 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_708_581 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_709_897 : nat64;};};}; record { ts = 1_720_915_198_910_706_388 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_722_224 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_723_363 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_723_856 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_722_971 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_721_557 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_722_813 : nat64;};};}; record { ts = 1_721_001_599_683_681_697 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_735_028 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_736_195 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_736_895 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_735_910 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_734_416 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_735_627 : nat64;};};}; record { ts = 1_721_087_999_904_777_181 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_747_751 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_749_350 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_749_810 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_748_745 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_747_228 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_748_482 : nat64;};};}; record { ts = 1_721_174_399_251_876_961 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_760_326 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_762_401 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_762_581 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_761_716 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_760_260 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_761_358 : nat64;};};}; record { ts = 1_721_260_799_590_889_198 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_773_126 : nat64;}; record { num_block_failures_total = 68 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_775_106 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_775_457 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_774_511 : nat64;}; record { num_block_failures_total = 70 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_772_928 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_773_914 : nat64;};};}; record { ts = 1_721_347_199_749_909_168 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_786_086 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_787_961 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_788_080 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_787_168 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_785_540 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_786_754 : nat64;};};}; record { ts = 1_721_433_599_883_710_941 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_799_163 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_800_615 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_801_000 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_800_072 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_798_386 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_799_669 : nat64;};};}; record { ts = 1_721_519_999_560_756_953 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_812_190 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_813_377 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_813_894 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_813_043 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_811_150 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_812_592 : nat64;};};}; record { ts = 1_721_606_399_618_868_422 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_825_069 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_826_308 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_826_643 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_825_851 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_824_191 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_825_528 : nat64;};};}; record { ts = 1_721_692_799_708_125_439 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_837_879 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_839_288 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_839_427 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_838_783 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_837_072 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_838_242 : nat64;};};}; record { ts = 1_721_779_199_416_468_524 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_850_629 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_852_125 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_852_372 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_851_618 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_849_941 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_851_119 : nat64;};};}; record { ts = 1_721_865_599_927_488_258 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 58 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_863_616 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_865_056 : nat64;}; record { num_block_failures_total = 51 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_865_276 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_864_484 : nat64;}; record { num_block_failures_total = 71 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_862_767 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_863_979 : nat64;};};}; record { ts = 1_721_951_998_934_090_476 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 59 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_876_310 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_877_878 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_878_148 : nat64;}; record { num_block_failures_total = 76 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_877_301 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_875_657 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_876_962 : nat64;};};}; record { ts = 1_722_038_399_476_499_196 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 59 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_889_213 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_890_644 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_891_059 : nat64;}; record { num_block_failures_total = 76 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_890_341 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_888_586 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_889_775 : nat64;};};}; record { ts = 1_722_124_799_451_395_655 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 59 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_902_008 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_903_332 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_904_042 : nat64;}; record { num_block_failures_total = 76 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_903_375 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_901_529 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_902_701 : nat64;};};}; record { ts = 1_722_211_199_022_265_393 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 59 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_915_083 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_916_137 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_916_814 : nat64;}; record { num_block_failures_total = 76 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_916_115 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_914_515 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_915_701 : nat64;};};}; record { ts = 1_722_297_598_880_602_693 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 59 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_927_845 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_928_983 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_929_756 : nat64;}; record { num_block_failures_total = 76 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_929_079 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_927_495 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_928_583 : nat64;};};}; record { ts = 1_722_383_999_973_967_169 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 59 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_940_696 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_942_028 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_942_647 : nat64;}; record { num_block_failures_total = 76 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_941_955 : nat64;}; record { num_block_failures_total = 74 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_940_187 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_941_595 : nat64;};};}; record { ts = 1_722_470_399_577_446_169 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 60 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_953_418 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_954_990 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_955_425 : nat64;}; record { num_block_failures_total = 77 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_954_707 : nat64;}; record { num_block_failures_total = 75 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_952_988 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_954_763 : nat64;};};}; record { ts = 1_722_556_799_604_228_415 : nat64; subnet_id = principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; node_metrics = vec { record { num_block_failures_total = 60 : nat64; node_id = principal "6bpfz-cjaos-uck3k-c5ex2-nkdvr-oql64-jet7u-yfmqo-zgxqv-qiftz-4qe"; num_blocks_proposed_total = 2_966_439 : nat64;}; record { num_block_failures_total = 69 : nat64; node_id = principal "n3hrq-akp7i-xednx-d2zd5-fl2xj-5hice-u2olr-5jacd-xrjvr-hbjy2-5qe"; num_blocks_proposed_total = 2_967_842 : nat64;}; record { num_block_failures_total = 52 : nat64; node_id = principal "5xplq-if2d4-h55o5-fwkps-i7jsb-xrnto-romgb-erfht-cmvqe-jsmhh-sae"; num_blocks_proposed_total = 2_968_329 : nat64;}; record { num_block_failures_total = 77 : nat64; node_id = principal "dlo4z-s65z7-ig6fn-zb2v5-s752c-jiva4-6ujh5-y7z2m-m2tht-ukzqf-3ae"; num_blocks_proposed_total = 2_967_694 : nat64;}; record { num_block_failures_total = 75 : nat64; node_id = principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"; num_blocks_proposed_total = 2_965_847 : nat64;}; record { num_block_failures_total = 83 : nat64; node_id = principal "gmqia-rpzvg-ttwje-2buta-jhfvv-v7hxf-djvgq-ss7i2-rzlbm-tziyn-kqe"; num_blocks_proposed_total = 2_967_512 : nat64;};};};} + }, +) diff --git a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh index cd448a976..1f4b61f20 100755 --- a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh +++ b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh @@ -1,3 +1,4 @@ + #!/bin/bash # Function to fetch logs and filter out new lines diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 557c34c05..d86d329c3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -1,8 +1,13 @@ +use candid::Principal; use ic_cdk_macros::*; use itertools::Itertools; -use std::time::Duration; -use types::{SubnetNodeMetricsArgs, SubnetNodeMetricsResponse}; +use std::{collections, time::Duration}; +use types::{ + NodeMetrics, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, + SubnetNodeMetricsResponse, TimestampNanos, +}; mod metrics_manager; +mod rewards_manager; mod stable_memory; pub mod types; @@ -39,7 +44,7 @@ fn post_upgrade() { fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result, String> { let from_ts = args.ts.unwrap_or_default(); - let metrics = stable_memory::get_metrics(from_ts); + let metrics = stable_memory::get_metrics_range(from_ts, None); let metrics_flat = metrics .into_iter() @@ -59,3 +64,34 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { + let period_start = args.from_ts; + let period_end = args.to_ts; + let metrics = stable_memory::get_metrics_range(period_start, Some(period_end)); + + let mut metrics_by_node: collections::BTreeMap> = collections::BTreeMap::new(); + for (ts, subnets) in metrics { + for subnet_metrics in subnets { + for node_metrics in subnet_metrics.node_metrics { + metrics_by_node.entry(node_metrics.node_id).or_default().push((ts, node_metrics)); + } + } + } + + let node_ids = metrics_by_node.keys().cloned().collect_vec(); + let initial_node_metrics = stable_memory::metrics_before_ts(node_ids, &period_start); + + + let result = metrics_by_node + .into_iter() + .map(|(node_id, metrics_in_period)| { + let node_rewards = rewards_manager::compute_rewards(metrics_in_period, initial_node_metrics.get(&node_id).cloned().unwrap()); + + NodeRewardsResponse { node_id, node_rewards } + }) + .collect_vec(); + + result +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs new file mode 100644 index 000000000..caea5557c --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -0,0 +1,113 @@ +use itertools::Itertools; + +use crate::types::{NodeMetrics, Rewards, TimestampNanos}; + +#[derive(Debug)] +pub struct DailyMetrics { + pub proposed_blocks: u64, + pub failed_blocks: u64, +} + +impl DailyMetrics { + pub fn new(proposed_blocks: u64, failed_blocks: u64) -> Self { + DailyMetrics { + proposed_blocks, + failed_blocks, + } + } + + pub fn failure_rates(&self) -> f64 { + let total_blocks = self.failed_blocks + self.proposed_blocks; + if total_blocks == 0 { + 0.0 + } else { + self.failed_blocks as f64 / total_blocks as f64 + } + } +} + +const MIN_FAILURE_RATE: f64 = 0.1; +const MAX_FAILURE_RATE: f64 = 0.7; + +fn calculate_rewards_no_penalty(failure_rates: &[f64]) -> f64 { + let sum: f64 = failure_rates.iter().sum(); + let average_failure_rate = sum / failure_rates.len() as f64; + + let reduction = if average_failure_rate < MIN_FAILURE_RATE { + 0.0 + } else if average_failure_rate > MAX_FAILURE_RATE { + 1.0 + } else { + (average_failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) + }; + + (1.0 - reduction) * 100.0 +} + +fn calculate_rewards_with_penalty(failure_rates: &[f64]) -> f64 { + let mut overall_reduction = 0.0; + let mut consecutive_days = 0; + let mut daily_reductions = Vec::new(); + let assigned_days = failure_rates.len() as f64; + + for &daily_failure_rate in failure_rates { + daily_reductions.push(daily_failure_rate); + + if daily_failure_rate >= MIN_FAILURE_RATE { + consecutive_days += 1; + } else if consecutive_days > 0 { + let penalty_weight = (consecutive_days * consecutive_days) as f64 / assigned_days; + let sum: f64 = failure_rates + .iter() + .skip(daily_reductions.len() - consecutive_days) + .take(consecutive_days) + .sum(); + let average_failure_rate = sum / consecutive_days as f64; + let penalty_reduction = average_failure_rate * penalty_weight; + overall_reduction += penalty_reduction; + consecutive_days = 0; + } + } + + if consecutive_days > 0 { + let penalty_weight = (consecutive_days * consecutive_days) as f64 / 30.0; + let sum: f64 = failure_rates + .iter() + .skip(daily_reductions.len() - consecutive_days) + .take(consecutive_days) + .sum(); + let average_failure_rate = sum / consecutive_days as f64; + let penalty_reduction = average_failure_rate * penalty_weight; + overall_reduction += penalty_reduction; + } + + overall_reduction += daily_reductions.iter().sum::(); + + 100.0 - overall_reduction +} + +pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_metrics: NodeMetrics) -> Rewards { + let mut daily_metrics = Vec::new(); + + metrics.sort_by_key(|&(timestamp, _)| timestamp); + + let mut previous_failed_total = initial_metrics.num_block_failures_total; + let mut previous_proposed_total = initial_metrics.num_blocks_proposed_total; + + for (_, node_metrics) in metrics { + let daily_proposed = node_metrics.num_blocks_proposed_total - previous_proposed_total; + let daily_failed = node_metrics.num_block_failures_total - previous_failed_total; + + daily_metrics.push(DailyMetrics::new(daily_proposed, daily_failed)); + + previous_failed_total = node_metrics.num_block_failures_total; + previous_proposed_total = node_metrics.num_blocks_proposed_total; + } + + let failure_rates = daily_metrics.iter().map(|metrics| metrics.failure_rates()).collect_vec(); + + Rewards { + rewards_standard: calculate_rewards_no_penalty(&failure_rates), + rewards_with_penalty: calculate_rewards_with_penalty(&failure_rates), + } +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index e93e6edb4..8d03d9b7c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -1,10 +1,12 @@ +use candid::Principal; use ic_stable_structures::{storable::Bound, Storable}; use ic_stable_structures::{DefaultMemoryImpl, StableBTreeMap}; use itertools::Itertools; use std::borrow::Cow; use std::cell::RefCell; +use std::collections::BTreeMap; -use crate::types::{SubnetNodeMetrics, SubnetNodeMetricsStorable, TimestampNanos}; +use crate::types::{NodeMetrics, SubnetNodeMetrics, SubnetNodeMetricsStorable, TimestampNanos}; impl Storable for SubnetNodeMetricsStorable { fn to_bytes(&self) -> Cow<[u8]> { @@ -33,6 +35,42 @@ pub fn latest_key() -> Option { MAP.with(|p| p.borrow().last_key_value()).map(|(k, _)| k) } -pub fn get_metrics(ts: TimestampNanos) -> Vec<(TimestampNanos, Vec)> { - MAP.with(|p| p.borrow().range(ts..).map(|(ts, storable)| (ts, storable.0)).collect_vec()) +pub fn get_metrics_range(from_ts: TimestampNanos, to_ts: Option) -> Vec<(TimestampNanos, Vec)> { + return MAP.with(|p| { + let borrowed = p.borrow(); + let metrics_in_range = match to_ts { + Some(to_ts) => borrowed.range(from_ts..=to_ts), + None => borrowed.range(from_ts..), + }; + metrics_in_range.into_iter().map(|(ts, storable)| (ts, storable.0)).collect_vec() + }); +} + +// Initialize metrics +pub fn metrics_before_ts(node_ids: Vec, ts: &TimestampNanos) -> BTreeMap { + let mut last_metrics: BTreeMap = BTreeMap::new(); + + // Initialize nodes + for node_id in node_ids { + last_metrics.insert(node_id, NodeMetrics{ + node_id, + num_block_failures_total: 0, + num_blocks_proposed_total: 0 + }); + } + + MAP.with(|p| { + let borrowed = p.borrow(); + + for (ts, metrics_storable) in borrowed.range(..ts) { + for subnet_metrics in metrics_storable.0 { + for node_metrics in subnet_metrics.node_metrics { + ic_cdk::println!("initial ts node {} {}", node_metrics.node_id, ts); + last_metrics.insert(node_metrics.node_id, node_metrics); + } + } + } + }); + + last_metrics } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index b02492eb9..e5cd76017 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -6,7 +6,7 @@ use serde::Serialize; pub type TimestampNanos = u64; pub type PrincipalNodeMetricsHistory = (PrincipalId, Vec); -#[derive(Debug, Deserialize, Serialize, CandidType)] +#[derive(Debug, Deserialize, Serialize, CandidType, Clone)] pub struct NodeMetrics { pub node_id: Principal, pub num_blocks_proposed_total: u64, @@ -34,3 +34,27 @@ pub struct SubnetNodeMetricsArgs { pub ts: Option, pub subnet_id: Option, } + +#[derive(Debug)] +pub struct RewardsMetrics { + pub rewards_standard: u64, + pub node_metrics: Vec, +} + +#[derive(Debug, Deserialize, Serialize, CandidType)] +pub struct Rewards { + pub rewards_standard: f64, + pub rewards_with_penalty: f64, +} + +#[derive(Debug, Deserialize, CandidType)] +pub struct NodeRewardsResponse { + pub node_id: Principal, + pub node_rewards: Rewards, +} + +#[derive(Deserialize, CandidType)] +pub struct NodeRewardsArgs { + pub from_ts: u64, + pub to_ts: u64, +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index 5440edd0d..affc6ce63 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -21,7 +21,22 @@ type SubnetNodeMetricsArgs = record { ts: opt nat64; }; +type Rewards = record { + rewards_standard: float64; + rewards_with_penalty: float64; +}; + +type NodeRewardsResponse = record { + node_id: principal; + node_rewards: Rewards; +}; + +type NodeRewardsArgs = record { + from_ts: nat64; + to_ts: nat64; +}; service : { "subnet_node_metrics" : (SubnetNodeMetricsArgs) -> (SubnetNodeMetricsResult) query; + "node_rewards" : (NodeRewardsArgs) -> (vec NodeRewardsResponse) query; } From 6603bf76add05fabbe3611d482170b5774c75237 Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 10:09:19 +0200 Subject: [PATCH 13/40] Add loading time in subnet chart --- .../trustworthy-node-metrics/args-rewards.bin | 1 - .../src/App.tsx | 80 +++++++++++++------ .../src/components/NodeList.tsx | 12 +-- .../src/components/RewardTable.tsx | 4 + .../src/components/SubnetChart.tsx | 4 +- .../src/models/NodeMetrics.tsx | 7 +- .../src/utils/utils.tsx | 7 ++ 7 files changed, 78 insertions(+), 37 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin index 17f73611c..f94c8b683 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin +++ b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin @@ -1,5 +1,4 @@ (record { from_ts = 1717372799135371824; to_ts = 1720655999188798300; - nodes = vec { principal "fpubd-4hk24-5wezd-yvbum-de5i6-kyspp-l3cce-lxcy2-7vugt-yso3r-7ae"}; }) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index e0680f966..c5d9eb814 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -4,11 +4,11 @@ import FilterBar, { PeriodFilter } from './components/FilterBar'; import Drawer from './components/Drawer'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; -import { SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; +import { NodeRewardsArgs, NodeRewardsResponse, Rewards, SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; import { DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; import { NodeList } from './components/NodeList'; import Header from './components/Header'; -import { calculateDailyValues, groupBy } from './utils/utils'; +import { calculateDailyValues, dateToNanoseconds, groupBy } from './utils/utils'; import { SubnetChart } from './components/SubnetChart'; const darkTheme = createTheme({ @@ -40,7 +40,9 @@ function App() { dateEnd: new Date() }); const [nodeMetrics, setnodeMetrics] = useState([]); - let subnets: Set = new Set(); + const [dashboardNodeMetrics, setDashboardNodeMetrics] = useState([]); + + const [subnets, setSubnets] = useState>(new Set()); const [nodeProviders, setNodeProviders] = useState>(new Set()); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(""); @@ -82,29 +84,59 @@ function App() { fetchNodes(); }, []); + useEffect(() => { + const updateRewards = async () => { + try { + setIsLoading(true) + const nodeRewardsMap = new Map(); + const request: NodeRewardsArgs = { + from_ts: dateToNanoseconds(periodFilter.dateStart), + to_ts: dateToNanoseconds(periodFilter.dateEnd), + }; - const dashboardNodeMetrics = useMemo(() => { - const metricsInPeriod = nodeMetrics.filter((metrics) => { - const metricsDate = metrics.date; - const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; - return isDateInRange; - }); - - subnets = new Set(nodeMetrics.map(metric => metric.subnetId.toText())); - - const grouped = groupBy(metricsInPeriod, 'nodeId'); - const groupedMetrics = Object.keys(grouped).map(nodeId => { - const items = grouped[nodeId]; - const dailyData = calculateDailyValues(items); - - return new DashboardNodeMetrics( - nodeId, - dailyData, - ); - }) - .sort((a, b) => b.failureRateAvg - a.failureRateAvg); + const nodeRewardsResponse: NodeRewardsResponse[] = await trustworthy_node_metrics.node_rewards(request); + nodeRewardsResponse.forEach((nodeReward) => { + + nodeRewardsMap.set(nodeReward.node_id.toText(), nodeReward.node_rewards); + }); + + const metricsInPeriod = nodeMetrics.filter((metrics) => { + const metricsDate = metrics.date; + const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; + return isDateInRange; + }); + + const subnets = new Set(nodeMetrics.map(metric => metric.subnetId.toText())); + + const grouped = groupBy(metricsInPeriod, 'nodeId'); + const groupedMetrics = Object.keys(grouped).map(nodeId => { + const items = grouped[nodeId]; + const dailyData = calculateDailyValues(items); + const rewards = nodeRewardsMap.get(nodeId)?.rewards_standard; + + if (rewards === undefined) { + throw new Error('rewards_standard is undefined'); + } + + return new DashboardNodeMetrics( + nodeId, + dailyData, + rewards + ); + }) + .sort((a, b) => a.rewardsNoPenalty - b.rewardsNoPenalty); + + setDashboardNodeMetrics(groupedMetrics); + setSubnets(subnets); - return groupedMetrics + } catch (error) { + console.error("Error fetching nodes:", error); + } finally { + setIsLoading(false); + } + }; + + updateRewards(); }, [periodFilter, nodeMetrics]); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index 6cbc7ab0c..b9d69bd29 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react'; -import { Box, Grid, Paper, Stack, Typography, Autocomplete, TextField } from '@mui/material'; +import { Box, Grid, Paper, Typography, Autocomplete, TextField } from '@mui/material'; import { axisClasses, BarChart } from '@mui/x-charts'; import { ChartData, DailyData, DashboardNodeMetrics } from '../models/NodeMetrics'; import { styled } from '@mui/material/styles'; import Divider from '@mui/material/Divider'; import { PeriodFilter } from './FilterBar'; -import { generateChartData, getFormattedDates, transformDailyData } from '../utils/utils'; +import { generateChartData} from '../utils/utils'; import FailureRateArc, { RewardsArc } from './Gauge'; export const Root = styled('div')(({ theme }) => ({ @@ -22,7 +22,7 @@ export interface NodeListProps { periodFilter: PeriodFilter } -function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: number, periodFilter: PeriodFilter): React.ReactNode { +function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: number, rewardsNoPenalty: number, periodFilter: PeriodFilter): React.ReactNode { const chartDailyData: ChartData[] = generateChartData(periodFilter, dailyData); @@ -34,7 +34,7 @@ function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: num {FailureRateArc(Math.round(failureRateAvg))} - {RewardsArc(Math.round(failureRateAvg))} + {RewardsArc(Math.round(rewardsNoPenalty))} @@ -109,9 +109,9 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period /> - {filteredMetrics.slice(0, 10).map(({ nodeId, dailyData, failureRateAvg }, index) => ( + {filteredMetrics.slice(0, 30).map(({ nodeId, dailyData, failureRateAvg, rewardsNoPenalty }, index) => ( - {renderChart(nodeId, dailyData, failureRateAvg, periodFilter)} + {renderChart(nodeId, dailyData, failureRateAvg, rewardsNoPenalty, periodFilter)} ))} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx index 7be98b0d9..26fba5197 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx @@ -22,6 +22,7 @@ const RewardTable: React.FC = ({ dashboardNodeMetrics }) => { Nodes Failure Rates Avg. + Rewards No Penalty @@ -36,6 +37,9 @@ const RewardTable: React.FC = ({ dashboardNodeMetrics }) => { {Math.round(nodeMetrics.failureRateAvg)}% + + {Math.round(nodeMetrics.rewardsNoPenalty)}% + ))} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx index 8dd840a6e..dad599591 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -41,7 +41,6 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, Daily Failure Rate - {chartData.length > 0 ? ( = ({ dashboardNodeMetrics, borderRadius={9} series={series} height={500} - />) : ()} + /> - diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx index 5ed69aaa3..a8bc9db56 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -53,18 +53,19 @@ export class DashboardNodeMetrics { nodeId: string; nodeIdSmall: string; dailyData: DailyData[]; - failureRateSum: number; failureRateAvg: number; + rewardsNoPenalty: number; constructor( nodeId: string, - dailyData: DailyData[] + dailyData: DailyData[], + rewardsNoPenalty: number, ) { this.nodeId = nodeId; this.nodeIdSmall = nodeId.split('-')[0]; this.dailyData = dailyData; - this.failureRateSum = dailyData.reduce((sum, item) => sum + item.failureRate, 0); this.failureRateAvg = computeAverageFailureRate(dailyData.map(elem => elem.failureRate)); + this.rewardsNoPenalty = rewardsNoPenalty; } public getChartSeries() { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx index 08e3252e8..4115c2ea0 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -1,6 +1,13 @@ import { PeriodFilter } from "../components/FilterBar"; import { ChartData, DailyData, NodeMetrics } from "../models/NodeMetrics"; + +export const dateToNanoseconds = (date: Date): bigint => { + const millisecondsSinceEpoch = date.getTime(); + const nanosecondsSinceEpoch = BigInt(millisecondsSinceEpoch) * BigInt(1_000_000); + return nanosecondsSinceEpoch; +}; + export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyData[]): ChartData[] => { const { dateStart, dateEnd } = periodFilter; const chartData: ChartData[] = []; From caf5f1d43a366cbc1b6e66ca1b7878f0228e16e4 Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 12:43:43 +0200 Subject: [PATCH 14/40] Add chrono dep --- Cargo.lock | 1 + .../.vite/deps_temp_a119c86f/package.json | 3 + .../src/trustworthy-node-metrics/Cargo.toml | 1 + .../src/trustworthy-node-metrics/src/lib.rs | 8 +- .../src/rewards_manager.rs | 114 ++++++++---------- 5 files changed, 60 insertions(+), 67 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.vite/deps_temp_a119c86f/package.json diff --git a/Cargo.lock b/Cargo.lock index a17fdbaf3..01d4e9cc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9168,6 +9168,7 @@ dependencies = [ "anyhow", "canbench-rs", "candid", + "chrono", "ciborium", "dfn_core", "futures", diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.vite/deps_temp_a119c86f/package.json b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.vite/deps_temp_a119c86f/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/.vite/deps_temp_a119c86f/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml index dd4c49695..5a019f639 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml @@ -33,3 +33,4 @@ ic-nns-common = { workspace = true } ic-registry-transport = { workspace = true } dfn_core = { workspace = true } canbench-rs = { version = "0.1.4", optional = true } +chrono = { workspace = true } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index d86d329c3..efe5fa370 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -2,10 +2,7 @@ use candid::Principal; use ic_cdk_macros::*; use itertools::Itertools; use std::{collections, time::Duration}; -use types::{ - NodeMetrics, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, - SubnetNodeMetricsResponse, TimestampNanos, -}; +use types::{NodeMetrics, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, SubnetNodeMetricsResponse, TimestampNanos}; mod metrics_manager; mod rewards_manager; mod stable_memory; @@ -70,8 +67,8 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { let period_start = args.from_ts; let period_end = args.to_ts; let metrics = stable_memory::get_metrics_range(period_start, Some(period_end)); - let mut metrics_by_node: collections::BTreeMap> = collections::BTreeMap::new(); + for (ts, subnets) in metrics { for subnet_metrics in subnets { for node_metrics in subnet_metrics.node_metrics { @@ -83,7 +80,6 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { let node_ids = metrics_by_node.keys().cloned().collect_vec(); let initial_node_metrics = stable_memory::metrics_before_ts(node_ids, &period_start); - let result = metrics_by_node .into_iter() .map(|(node_id, metrics_in_period)| { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index caea5557c..14057e363 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,27 +1,31 @@ -use itertools::Itertools; +use chrono::{DateTime, Duration, Utc}; use crate::types::{NodeMetrics, Rewards, TimestampNanos}; #[derive(Debug)] pub struct DailyMetrics { + pub datetime: DateTime, pub proposed_blocks: u64, pub failed_blocks: u64, + failure_rate: f64, } impl DailyMetrics { - pub fn new(proposed_blocks: u64, failed_blocks: u64) -> Self { + pub fn new(ts_nanos: TimestampNanos, proposed_blocks: u64, failed_blocks: u64) -> Self { + let secs = (ts_nanos / 1_000_000_000) as i64; + let nanos = (secs % 1_000_000_000) as u32; + let total_blocks = failed_blocks + proposed_blocks; + let failure_rate = if total_blocks == 0 { + 0.0 + } else { + failed_blocks as f64 / total_blocks as f64 + }; + DailyMetrics { + datetime: DateTime::::from_timestamp(secs, nanos).unwrap(), proposed_blocks, failed_blocks, - } - } - - pub fn failure_rates(&self) -> f64 { - let total_blocks = self.failed_blocks + self.proposed_blocks; - if total_blocks == 0 { - 0.0 - } else { - self.failed_blocks as f64 / total_blocks as f64 + failure_rate, } } } @@ -29,61 +33,49 @@ impl DailyMetrics { const MIN_FAILURE_RATE: f64 = 0.1; const MAX_FAILURE_RATE: f64 = 0.7; -fn calculate_rewards_no_penalty(failure_rates: &[f64]) -> f64 { - let sum: f64 = failure_rates.iter().sum(); - let average_failure_rate = sum / failure_rates.len() as f64; - - let reduction = if average_failure_rate < MIN_FAILURE_RATE { +fn daily_reduction(failure_rate: &f64) -> f64 { + if failure_rate < &MIN_FAILURE_RATE { 0.0 - } else if average_failure_rate > MAX_FAILURE_RATE { + } else if failure_rate > &MAX_FAILURE_RATE { 1.0 } else { - (average_failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) - }; - - (1.0 - reduction) * 100.0 + (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) + } } -fn calculate_rewards_with_penalty(failure_rates: &[f64]) -> f64 { - let mut overall_reduction = 0.0; - let mut consecutive_days = 0; - let mut daily_reductions = Vec::new(); - let assigned_days = failure_rates.len() as f64; - - for &daily_failure_rate in failure_rates { - daily_reductions.push(daily_failure_rate); - - if daily_failure_rate >= MIN_FAILURE_RATE { - consecutive_days += 1; - } else if consecutive_days > 0 { - let penalty_weight = (consecutive_days * consecutive_days) as f64 / assigned_days; - let sum: f64 = failure_rates - .iter() - .skip(daily_reductions.len() - consecutive_days) - .take(consecutive_days) - .sum(); - let average_failure_rate = sum / consecutive_days as f64; - let penalty_reduction = average_failure_rate * penalty_weight; - overall_reduction += penalty_reduction; - consecutive_days = 0; +fn calculate_reduction(metrics: &[DailyMetrics]) -> (f64, f64) { + let active_days = metrics.len(); + + let mut day_tracker = metrics[0].datetime; + let mut consecutive_days = Vec::new(); + let mut reduction_with_penalty = 0 as f64; + + let reduction_no_penalty = metrics.iter().fold(0 as f64, |mut acc, daily_metrics| { + acc += daily_reduction(&daily_metrics.failure_rate); + acc + }) / (active_days as f64); + + for daily_metrics in metrics { + let daily_reduction = daily_reduction(&daily_metrics.failure_rate); + let is_day_after = daily_metrics.datetime.date_naive() == day_tracker.date_naive() + Duration::days(1); + + if daily_reduction == 0 as f64 { + if !consecutive_days.is_empty() { + reduction_with_penalty += consecutive_days.len() as f64 * consecutive_days.iter().sum::(); + consecutive_days.clear(); + } + } else if is_day_after { + consecutive_days.push(daily_reduction) + } else { + reduction_with_penalty += daily_reduction } - } - if consecutive_days > 0 { - let penalty_weight = (consecutive_days * consecutive_days) as f64 / 30.0; - let sum: f64 = failure_rates - .iter() - .skip(daily_reductions.len() - consecutive_days) - .take(consecutive_days) - .sum(); - let average_failure_rate = sum / consecutive_days as f64; - let penalty_reduction = average_failure_rate * penalty_weight; - overall_reduction += penalty_reduction; + day_tracker = daily_metrics.datetime; } - overall_reduction += daily_reductions.iter().sum::(); + reduction_with_penalty /= active_days as f64; - 100.0 - overall_reduction + (reduction_no_penalty, reduction_with_penalty) } pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_metrics: NodeMetrics) -> Rewards { @@ -94,20 +86,20 @@ pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_ let mut previous_failed_total = initial_metrics.num_block_failures_total; let mut previous_proposed_total = initial_metrics.num_blocks_proposed_total; - for (_, node_metrics) in metrics { + for (ts_nanos, node_metrics) in metrics { let daily_proposed = node_metrics.num_blocks_proposed_total - previous_proposed_total; let daily_failed = node_metrics.num_block_failures_total - previous_failed_total; - daily_metrics.push(DailyMetrics::new(daily_proposed, daily_failed)); + daily_metrics.push(DailyMetrics::new(ts_nanos, daily_proposed, daily_failed)); previous_failed_total = node_metrics.num_block_failures_total; previous_proposed_total = node_metrics.num_blocks_proposed_total; } - let failure_rates = daily_metrics.iter().map(|metrics| metrics.failure_rates()).collect_vec(); + let (reduction_no_penalty, reduction_with_penalty) = calculate_reduction(&daily_metrics); Rewards { - rewards_standard: calculate_rewards_no_penalty(&failure_rates), - rewards_with_penalty: calculate_rewards_with_penalty(&failure_rates), + rewards_standard: (1.0 - reduction_no_penalty) * 100.0, + rewards_with_penalty: (1.0 - reduction_with_penalty) * 100.0, } } From 5440ce911497beca1830ad13d4ddd8e9dd577e76 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 5 Aug 2024 10:48:01 +0000 Subject: [PATCH 15/40] Github Action: Bazel Repin --- Cargo.Bazel.lock | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index b8a2d11c4..2d160c6d3 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "122ae00e2b90aff46a0aaf1e6e2d80c5729af927eb65d305a5e598b381eed7b1", + "checksum": "b8f55a45d154895cfe0bec839ab21692ca278f057c5cf6afa56dc8c946e2620f", "crates": { "actix-codec 0.5.2": { "name": "actix-codec", @@ -45910,6 +45910,10 @@ "id": "candid 0.10.9", "target": "candid" }, + { + "id": "chrono 0.4.38", + "target": "chrono" + }, { "id": "ciborium 0.2.2", "target": "ciborium" From 23aa22414703d310234885197d36121501add1be Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 16:57:07 +0200 Subject: [PATCH 16/40] Add failure rate response --- .../src/trustworthy-node-metrics/Cargo.toml | 2 +- .../src/trustworthy-node-metrics/src/lib.rs | 2 +- .../src/rewards_manager.rs | 35 +++++++++++-------- .../src/stable_memory.rs | 5 +-- .../src/trustworthy-node-metrics/src/types.rs | 10 +++--- .../trustworthy-node-metrics.did | 8 ++++- 6 files changed, 37 insertions(+), 25 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml index 5a019f639..9122107da 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml @@ -33,4 +33,4 @@ ic-nns-common = { workspace = true } ic-registry-transport = { workspace = true } dfn_core = { workspace = true } canbench-rs = { version = "0.1.4", optional = true } -chrono = { workspace = true } +chrono = { version = "0.4", default-features = false, features = ["serde"] } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index efe5fa370..3514f0c5e 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -62,7 +62,7 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { let period_start = args.from_ts; let period_end = args.to_ts; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index 14057e363..8ad09b14a 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,16 +1,24 @@ use chrono::{DateTime, Duration, Utc}; +use itertools::Itertools; -use crate::types::{NodeMetrics, Rewards, TimestampNanos}; +use crate::types::{DailyFailureRateResponse, NodeMetrics, Rewards, TimestampNanos}; #[derive(Debug)] -pub struct DailyMetrics { +pub struct DailyFailureRate { pub datetime: DateTime, - pub proposed_blocks: u64, - pub failed_blocks: u64, - failure_rate: f64, + pub failure_rate: f64, } -impl DailyMetrics { +impl From for DailyFailureRateResponse { + fn from(metrics: DailyFailureRate) -> Self { + DailyFailureRateResponse { + date_ts: metrics.datetime.timestamp_nanos_opt().unwrap() as u64, + failure_rate: metrics.failure_rate, + } + } +} + +impl DailyFailureRate { pub fn new(ts_nanos: TimestampNanos, proposed_blocks: u64, failed_blocks: u64) -> Self { let secs = (ts_nanos / 1_000_000_000) as i64; let nanos = (secs % 1_000_000_000) as u32; @@ -21,10 +29,8 @@ impl DailyMetrics { failed_blocks as f64 / total_blocks as f64 }; - DailyMetrics { - datetime: DateTime::::from_timestamp(secs, nanos).unwrap(), - proposed_blocks, - failed_blocks, + DailyFailureRate { + datetime: chrono::DateTime::::from_timestamp(secs, nanos).unwrap(), failure_rate, } } @@ -43,7 +49,7 @@ fn daily_reduction(failure_rate: &f64) -> f64 { } } -fn calculate_reduction(metrics: &[DailyMetrics]) -> (f64, f64) { +fn calculate_reduction(metrics: &[DailyFailureRate]) -> (f64, f64) { let active_days = metrics.len(); let mut day_tracker = metrics[0].datetime; @@ -79,7 +85,7 @@ fn calculate_reduction(metrics: &[DailyMetrics]) -> (f64, f64) { } pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_metrics: NodeMetrics) -> Rewards { - let mut daily_metrics = Vec::new(); + let mut daily_failure_rate = Vec::new(); metrics.sort_by_key(|&(timestamp, _)| timestamp); @@ -90,15 +96,16 @@ pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_ let daily_proposed = node_metrics.num_blocks_proposed_total - previous_proposed_total; let daily_failed = node_metrics.num_block_failures_total - previous_failed_total; - daily_metrics.push(DailyMetrics::new(ts_nanos, daily_proposed, daily_failed)); + daily_failure_rate.push(DailyFailureRate::new(ts_nanos, daily_proposed, daily_failed)); previous_failed_total = node_metrics.num_block_failures_total; previous_proposed_total = node_metrics.num_blocks_proposed_total; } - let (reduction_no_penalty, reduction_with_penalty) = calculate_reduction(&daily_metrics); + let (reduction_no_penalty, reduction_with_penalty) = calculate_reduction(&daily_failure_rate); Rewards { + daily_failure_rate: daily_failure_rate.into_iter().map(|fr| fr.into()).collect_vec(), rewards_standard: (1.0 - reduction_no_penalty) * 100.0, rewards_with_penalty: (1.0 - reduction_with_penalty) * 100.0, } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 8d03d9b7c..b003f61f3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -46,11 +46,9 @@ pub fn get_metrics_range(from_ts: TimestampNanos, to_ts: Option) }); } -// Initialize metrics pub fn metrics_before_ts(node_ids: Vec, ts: &TimestampNanos) -> BTreeMap { let mut last_metrics: BTreeMap = BTreeMap::new(); - // Initialize nodes for node_id in node_ids { last_metrics.insert(node_id, NodeMetrics{ node_id, @@ -62,10 +60,9 @@ pub fn metrics_before_ts(node_ids: Vec, ts: &TimestampNanos) -> BTree MAP.with(|p| { let borrowed = p.borrow(); - for (ts, metrics_storable) in borrowed.range(..ts) { + for (_, metrics_storable) in borrowed.range(..ts) { for subnet_metrics in metrics_storable.0 { for node_metrics in subnet_metrics.node_metrics { - ic_cdk::println!("initial ts node {} {}", node_metrics.node_id, ts); last_metrics.insert(node_metrics.node_id, node_metrics); } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index e5cd76017..8712cb178 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -1,4 +1,5 @@ use candid::{CandidType, Deserialize, Principal}; +use chrono::{DateTime, Utc}; use dfn_core::api::PrincipalId; use ic_management_canister_types::NodeMetricsHistoryResponse; use serde::Serialize; @@ -35,14 +36,15 @@ pub struct SubnetNodeMetricsArgs { pub subnet_id: Option, } -#[derive(Debug)] -pub struct RewardsMetrics { - pub rewards_standard: u64, - pub node_metrics: Vec, +#[derive(Debug, Deserialize, Serialize, CandidType)] +pub struct DailyFailureRateResponse { + pub date_ts: TimestampNanos, + pub failure_rate: f64, } #[derive(Debug, Deserialize, Serialize, CandidType)] pub struct Rewards { + pub daily_failure_rate: Vec, pub rewards_standard: f64, pub rewards_with_penalty: f64, } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index affc6ce63..1721ba550 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -21,7 +21,13 @@ type SubnetNodeMetricsArgs = record { ts: opt nat64; }; +type DailyFailureRateResponse = record { + date_ts: opt nat64; + failure_rate: opt float64; +}; + type Rewards = record { + daily_failure_rate: vec DailyFailureRateResponse; rewards_standard: float64; rewards_with_penalty: float64; }; @@ -38,5 +44,5 @@ type NodeRewardsArgs = record { service : { "subnet_node_metrics" : (SubnetNodeMetricsArgs) -> (SubnetNodeMetricsResult) query; - "node_rewards" : (NodeRewardsArgs) -> (vec NodeRewardsResponse) query; + "node_rewards" : (NodeRewardsArgs) -> (vec NodeRewardsResponse); } From 390cf6da6ec20ca3d34fa8159e181fc20d145f10 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 5 Aug 2024 15:01:06 +0000 Subject: [PATCH 17/40] Github Action: Bazel Repin --- Cargo.Bazel.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 2d160c6d3..e364664ee 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "b8f55a45d154895cfe0bec839ab21692ca278f057c5cf6afa56dc8c946e2620f", + "checksum": "d063b72b678016845706fca5f3e3c1d5f43492ba220e8513e2aa9a47b0b5a493", "crates": { "actix-codec 0.5.2": { "name": "actix-codec", From b4885ae87159f01289e696e8f83b502834cc342c Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 17:46:03 +0200 Subject: [PATCH 18/40] Remove daily failure rate computation --- .../trustworthy-node-metrics/src/rewards_manager.rs | 13 +------------ .../src/trustworthy-node-metrics/src/types.rs | 7 ------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index 8ad09b14a..b30c789a9 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,7 +1,6 @@ use chrono::{DateTime, Duration, Utc}; -use itertools::Itertools; -use crate::types::{DailyFailureRateResponse, NodeMetrics, Rewards, TimestampNanos}; +use crate::types::{NodeMetrics, Rewards, TimestampNanos}; #[derive(Debug)] pub struct DailyFailureRate { @@ -9,15 +8,6 @@ pub struct DailyFailureRate { pub failure_rate: f64, } -impl From for DailyFailureRateResponse { - fn from(metrics: DailyFailureRate) -> Self { - DailyFailureRateResponse { - date_ts: metrics.datetime.timestamp_nanos_opt().unwrap() as u64, - failure_rate: metrics.failure_rate, - } - } -} - impl DailyFailureRate { pub fn new(ts_nanos: TimestampNanos, proposed_blocks: u64, failed_blocks: u64) -> Self { let secs = (ts_nanos / 1_000_000_000) as i64; @@ -105,7 +95,6 @@ pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_ let (reduction_no_penalty, reduction_with_penalty) = calculate_reduction(&daily_failure_rate); Rewards { - daily_failure_rate: daily_failure_rate.into_iter().map(|fr| fr.into()).collect_vec(), rewards_standard: (1.0 - reduction_no_penalty) * 100.0, rewards_with_penalty: (1.0 - reduction_with_penalty) * 100.0, } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index 8712cb178..d8154f074 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -36,15 +36,8 @@ pub struct SubnetNodeMetricsArgs { pub subnet_id: Option, } -#[derive(Debug, Deserialize, Serialize, CandidType)] -pub struct DailyFailureRateResponse { - pub date_ts: TimestampNanos, - pub failure_rate: f64, -} - #[derive(Debug, Deserialize, Serialize, CandidType)] pub struct Rewards { - pub daily_failure_rate: Vec, pub rewards_standard: f64, pub rewards_with_penalty: f64, } From 46fed516f2343f0244de5921f7e7b0dc84ead25e Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 18:57:02 +0200 Subject: [PATCH 19/40] Fixing daily fr computation --- .../src/App.tsx | 40 +++++++++++-------- .../src/components/SubnetChart.tsx | 1 - .../src/models/NodeMetrics.tsx | 16 +++++--- .../src/trustworthy-node-metrics/src/types.rs | 1 - 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index c5d9eb814..d1687fe90 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -5,7 +5,7 @@ import Drawer from './components/Drawer'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; import { NodeRewardsArgs, NodeRewardsResponse, Rewards, SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; -import { DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; +import { DailyNodeMetrics, DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; import { NodeList } from './components/NodeList'; import Header from './components/Header'; import { calculateDailyValues, dateToNanoseconds, groupBy } from './utils/utils'; @@ -39,7 +39,7 @@ function App() { dateStart: thirtyDaysAgo, dateEnd: new Date() }); - const [nodeMetrics, setnodeMetrics] = useState([]); + const [dailyNodeMetrics, setDailyNodeMetrics] = useState([]); const [dashboardNodeMetrics, setDashboardNodeMetrics] = useState([]); const [subnets, setSubnets] = useState>(new Set()); @@ -70,7 +70,20 @@ function App() { }) }); - setnodeMetrics(metrics); + const grouped = groupBy(metrics, 'nodeId'); + const dailyNodeMetrics = Object.keys(grouped).flatMap(nodeId => { + const items = grouped[nodeId]; + const dailyData = calculateDailyValues(items); + + return dailyData.map(daily => { + return new DailyNodeMetrics( + nodeId, + daily, + ) + } + )}); + + setDailyNodeMetrics(dailyNodeMetrics); } else { setError(response.Err); } @@ -93,26 +106,19 @@ function App() { from_ts: dateToNanoseconds(periodFilter.dateStart), to_ts: dateToNanoseconds(periodFilter.dateEnd), }; - const nodeRewardsResponse: NodeRewardsResponse[] = await trustworthy_node_metrics.node_rewards(request); nodeRewardsResponse.forEach((nodeReward) => { - nodeRewardsMap.set(nodeReward.node_id.toText(), nodeReward.node_rewards); }); - const metricsInPeriod = nodeMetrics.filter((metrics) => { - const metricsDate = metrics.date; + const metricsInPeriod = dailyNodeMetrics.filter((metrics) => { + const metricsDate = metrics.dailyData.date; const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; return isDateInRange; }); - - const subnets = new Set(nodeMetrics.map(metric => metric.subnetId.toText())); - const grouped = groupBy(metricsInPeriod, 'nodeId'); const groupedMetrics = Object.keys(grouped).map(nodeId => { - const items = grouped[nodeId]; - const dailyData = calculateDailyValues(items); - const rewards = nodeRewardsMap.get(nodeId)?.rewards_standard; + const rewards = nodeRewardsMap.get(nodeId); if (rewards === undefined) { throw new Error('rewards_standard is undefined'); @@ -120,12 +126,14 @@ function App() { return new DashboardNodeMetrics( nodeId, - dailyData, - rewards + grouped[nodeId].map(data => data.dailyData), + rewards.rewards_standard ); }) .sort((a, b) => a.rewardsNoPenalty - b.rewardsNoPenalty); + const subnets = new Set(metricsInPeriod.map(metric => metric.dailyData.subnetId)); + setDashboardNodeMetrics(groupedMetrics); setSubnets(subnets); @@ -137,7 +145,7 @@ function App() { }; updateRewards(); - }, [periodFilter, nodeMetrics]); + }, [periodFilter, dailyNodeMetrics]); if (error) { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx index dad599591..57fcfb91f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -4,7 +4,6 @@ import { axisClasses, BarChart, StackOrderType } from '@mui/x-charts'; import Divider from '@mui/material/Divider'; import { useParams } from 'react-router-dom'; import { generateChartData, getFormattedDates } from '../utils/utils'; -import { ChartsNoDataOverlay } from '@mui/x-charts/ChartsOverlay'; import RewardTable from './RewardTable'; import { DashboardNodeMetrics } from '../models/NodeMetrics'; import { PeriodFilter } from './FilterBar'; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx index a8bc9db56..1dfaa4135 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -67,11 +67,17 @@ export class DashboardNodeMetrics { this.failureRateAvg = computeAverageFailureRate(dailyData.map(elem => elem.failureRate)); this.rewardsNoPenalty = rewardsNoPenalty; } +} + +export class DailyNodeMetrics { + nodeId: string; + dailyData: DailyData; - public getChartSeries() { - return { - data: this.dailyData.map(daily => daily.failureRate), - label: this.nodeId, - }; + constructor( + nodeId: string, + dailyData: DailyData + ) { + this.nodeId = nodeId; + this.dailyData = dailyData; } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index d8154f074..ee9536c02 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -1,5 +1,4 @@ use candid::{CandidType, Deserialize, Principal}; -use chrono::{DateTime, Utc}; use dfn_core::api::PrincipalId; use ic_management_canister_types::NodeMetricsHistoryResponse; use serde::Serialize; From 0037042a9ccf0aceb8a2f483492a6dbaf146b2f3 Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 18:58:58 +0200 Subject: [PATCH 20/40] fix did file --- .../src/trustworthy-node-metrics/src/lib.rs | 2 +- .../src/trustworthy-node-metrics/src/types.rs | 1 - .../src/trustworthy-node-metrics/trustworthy-node-metrics.did | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 3514f0c5e..efe5fa370 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -62,7 +62,7 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { let period_start = args.from_ts; let period_end = args.to_ts; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index d8154f074..ee9536c02 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -1,5 +1,4 @@ use candid::{CandidType, Deserialize, Principal}; -use chrono::{DateTime, Utc}; use dfn_core::api::PrincipalId; use ic_management_canister_types::NodeMetricsHistoryResponse; use serde::Serialize; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index 1721ba550..505e8108e 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -44,5 +44,5 @@ type NodeRewardsArgs = record { service : { "subnet_node_metrics" : (SubnetNodeMetricsArgs) -> (SubnetNodeMetricsResult) query; - "node_rewards" : (NodeRewardsArgs) -> (vec NodeRewardsResponse); + "node_rewards" : (NodeRewardsArgs) -> (vec NodeRewardsResponse) query; } From 4994fd01e5563c3b6a9b4ce0f1135ce3f9dbf9df Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 5 Aug 2024 19:03:36 +0200 Subject: [PATCH 21/40] Removing daily failure rate --- .../trustworthy-node-metrics/trustworthy-node-metrics.did | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index 505e8108e..affc6ce63 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -21,13 +21,7 @@ type SubnetNodeMetricsArgs = record { ts: opt nat64; }; -type DailyFailureRateResponse = record { - date_ts: opt nat64; - failure_rate: opt float64; -}; - type Rewards = record { - daily_failure_rate: vec DailyFailureRateResponse; rewards_standard: float64; rewards_with_penalty: float64; }; From bd456d9934fd509bec93bc11f0cd4216aeb0f3df Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 6 Aug 2024 20:06:13 +0200 Subject: [PATCH 22/40] Fix API single call --- .../src/App.tsx | 128 ++++-------------- .../src/components/Gauge.tsx | 6 +- .../src/components/NodeList.tsx | 20 +-- .../src/components/RewardTable.tsx | 12 +- .../src/components/SubnetChart.tsx | 14 +- .../src/models/NodeMetrics.tsx | 77 ++--------- .../src/utils/utils.tsx | 83 +++--------- .../src/trustworthy-node-metrics/src/lib.rs | 17 ++- .../src/rewards_manager.rs | 96 +++++++------ .../src/trustworthy-node-metrics/src/types.rs | 11 +- .../trustworthy-node-metrics.did | 11 +- 11 files changed, 165 insertions(+), 310 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index d1687fe90..b01665c0b 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -1,14 +1,14 @@ -import React, { useState, useEffect, useMemo } from 'react'; +import React, { useState, useEffect } from 'react'; import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; import FilterBar, { PeriodFilter } from './components/FilterBar'; import Drawer from './components/Drawer'; -import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; -import { NodeRewardsArgs, NodeRewardsResponse, Rewards, SubnetNodeMetricsArgs, SubnetNodeMetricsResult } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; -import { DailyNodeMetrics, DashboardNodeMetrics, NodeMetrics } from './models/NodeMetrics'; +import { NodeRewardsArgs, NodeRewardsResponse } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; +import { DashboardNodeRewards } from './models/NodeMetrics'; import { NodeList } from './components/NodeList'; import Header from './components/Header'; -import { calculateDailyValues, dateToNanoseconds, groupBy } from './utils/utils'; +import { dateToNanoseconds } from './utils/utils'; import { SubnetChart } from './components/SubnetChart'; const darkTheme = createTheme({ @@ -32,125 +32,59 @@ const LoadingIndicator: React.FC = () => ( ); function App() { - const thirtyDaysAgo = new Date(); - thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); + const dateStart = new Date(); + const dateEnd = new Date(); + dateStart.setDate(dateStart.getDate() - 30); + dateStart.setHours(0, 0, 0, 0); + dateEnd.setHours(23, 59, 59, 999); const [periodFilter, setPeriodFilter] = useState({ - dateStart: thirtyDaysAgo, - dateEnd: new Date() + dateStart: dateStart, + dateEnd: dateEnd }); - const [dailyNodeMetrics, setDailyNodeMetrics] = useState([]); - const [dashboardNodeMetrics, setDashboardNodeMetrics] = useState([]); + + const [dashboardNodeRewards, setDashboardNodeRewards] = useState([]); const [subnets, setSubnets] = useState>(new Set()); const [nodeProviders, setNodeProviders] = useState>(new Set()); const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(""); const drawerWidth = 180; - useEffect(() => { - const fetchNodes = async () => { - try { - const request: SubnetNodeMetricsArgs = { - ts: [], - subnet_id: [], - }; - const response: SubnetNodeMetricsResult = await trustworthy_node_metrics.subnet_node_metrics(request); - - if ('Ok' in response) { - const metrics: NodeMetrics[] = response.Ok.flatMap((metricResponse) => { - return metricResponse.node_metrics.map((nodeMetrics) => { - return new NodeMetrics( - metricResponse.ts, - nodeMetrics.num_block_failures_total, - nodeMetrics.node_id, - nodeMetrics.num_blocks_proposed_total, - metricResponse.subnet_id - ); - }) - }); - - const grouped = groupBy(metrics, 'nodeId'); - const dailyNodeMetrics = Object.keys(grouped).flatMap(nodeId => { - const items = grouped[nodeId]; - const dailyData = calculateDailyValues(items); - - return dailyData.map(daily => { - return new DailyNodeMetrics( - nodeId, - daily, - ) - } - )}); - - setDailyNodeMetrics(dailyNodeMetrics); - } else { - setError(response.Err); - } - } catch (error) { - console.error("Error fetching nodes:", error); - } finally { - setIsLoading(false); - } - }; - - fetchNodes(); - }, []); - useEffect(() => { const updateRewards = async () => { try { setIsLoading(true) - const nodeRewardsMap = new Map(); + const c = periodFilter.dateStart.setHours(0, 0, 0, 0); const request: NodeRewardsArgs = { from_ts: dateToNanoseconds(periodFilter.dateStart), to_ts: dateToNanoseconds(periodFilter.dateEnd), }; const nodeRewardsResponse: NodeRewardsResponse[] = await trustworthy_node_metrics.node_rewards(request); - nodeRewardsResponse.forEach((nodeReward) => { - nodeRewardsMap.set(nodeReward.node_id.toText(), nodeReward.node_rewards); - }); - - const metricsInPeriod = dailyNodeMetrics.filter((metrics) => { - const metricsDate = metrics.dailyData.date; - const isDateInRange = metricsDate >= periodFilter.dateStart && metricsDate <= periodFilter.dateEnd; - return isDateInRange; - }); - const grouped = groupBy(metricsInPeriod, 'nodeId'); - const groupedMetrics = Object.keys(grouped).map(nodeId => { - const rewards = nodeRewardsMap.get(nodeId); - if (rewards === undefined) { - throw new Error('rewards_standard is undefined'); - } - - return new DashboardNodeMetrics( - nodeId, - grouped[nodeId].map(data => data.dailyData), - rewards.rewards_standard + const dashboardNodeRewards = nodeRewardsResponse.map((nodeRewards) => { + return new DashboardNodeRewards( + nodeRewards.node_id, + nodeRewards.daily_data, + nodeRewards.rewards_no_penalty, + nodeRewards.rewards_with_penalty, ); - }) - .sort((a, b) => a.rewardsNoPenalty - b.rewardsNoPenalty); + }).sort((a, b) => a.rewardsNoPenalty - b.rewardsNoPenalty ); + - const subnets = new Set(metricsInPeriod.map(metric => metric.dailyData.subnetId)); + const subnets = new Set(dashboardNodeRewards.flatMap(nodeRewards => nodeRewards.dailyData.map( data => data.subnet_id.toText()))); - setDashboardNodeMetrics(groupedMetrics); + setDashboardNodeRewards(dashboardNodeRewards); setSubnets(subnets); } catch (error) { - console.error("Error fetching nodes:", error); + console.error("Error fetching node:", error); } finally { setIsLoading(false); } }; updateRewards(); - }, [periodFilter, dailyNodeMetrics]); - - - if (error) { - return
Error: {error}
; - } + }, [periodFilter]); return ( @@ -175,14 +109,12 @@ function App() { /> - ) : ()} - /> + } /> ) : ()} + isLoading ? () : ()} /> ) : ()} + isLoading ? () : ()} /> diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx index 55604e846..c8da66d30 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx @@ -6,12 +6,12 @@ export default function FailureRateArc(value: number) { return ( - Failure Rate + Failure Rate Average `${value}%` @@ -41,7 +41,7 @@ export function RewardsArc(value: number) { `${value}%` diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index b9d69bd29..a542a59b0 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -1,12 +1,14 @@ import React, { useState } from 'react'; import { Box, Grid, Paper, Typography, Autocomplete, TextField } from '@mui/material'; import { axisClasses, BarChart } from '@mui/x-charts'; -import { ChartData, DailyData, DashboardNodeMetrics } from '../models/NodeMetrics'; +import { ChartData, DashboardNodeRewards } from '../models/NodeMetrics'; import { styled } from '@mui/material/styles'; import Divider from '@mui/material/Divider'; import { PeriodFilter } from './FilterBar'; import { generateChartData} from '../utils/utils'; import FailureRateArc, { RewardsArc } from './Gauge'; +import { Principal } from '@dfinity/principal'; +import { DailyNodeData } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; export const Root = styled('div')(({ theme }) => ({ width: '100%', @@ -18,11 +20,11 @@ export const Root = styled('div')(({ theme }) => ({ })); export interface NodeListProps { - dashboardNodeMetrics: DashboardNodeMetrics[], + dashboardNodeMetrics: DashboardNodeRewards[], periodFilter: PeriodFilter } -function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: number, rewardsNoPenalty: number, periodFilter: PeriodFilter): React.ReactNode { +function renderChart(nodeId: Principal, dailyData: DailyNodeData[], failureRateAvg: number, rewardsNoPenalty: number, periodFilter: PeriodFilter): React.ReactNode { const chartDailyData: ChartData[] = generateChartData(periodFilter, dailyData); @@ -30,11 +32,11 @@ function renderChart(nodeId: string, dailyData: DailyData[], failureRateAvg: num - {nodeId} + {nodeId.toText()} - {FailureRateArc(Math.round(failureRateAvg))} - {RewardsArc(Math.round(rewardsNoPenalty))} + {FailureRateArc(failureRateAvg)} + {RewardsArc(rewardsNoPenalty)} @@ -87,7 +89,7 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period const handleSearchChange = (event: unknown, value: string | null) => { if (value) { - const filtered = dashboardNodeMetrics.filter(node => node.nodeId.includes(value)); + const filtered = dashboardNodeMetrics.filter(node => node.nodeId.toText().includes(value)); setFilteredMetrics(filtered); } else { setFilteredMetrics(dashboardNodeMetrics); @@ -101,7 +103,7 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period node.nodeId)} + options={dashboardNodeMetrics.map((node) => node.nodeId.toText())} onInputChange={handleSearchChange} renderInput={(params) => ( @@ -109,7 +111,7 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period /> - {filteredMetrics.slice(0, 30).map(({ nodeId, dailyData, failureRateAvg, rewardsNoPenalty }, index) => ( + {filteredMetrics.slice(0, 20).map(({ nodeId, dailyData, failureRateAvg, rewardsNoPenalty }, index) => ( {renderChart(nodeId, dailyData, failureRateAvg, rewardsNoPenalty, periodFilter)} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx index 26fba5197..155fe417b 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx @@ -6,11 +6,11 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Paper from '@mui/material/Paper'; -import { DashboardNodeMetrics } from '../models/NodeMetrics'; +import { DashboardNodeRewards } from '../models/NodeMetrics'; import { SxProps, Theme } from '@mui/material'; interface RewardTableProps { - dashboardNodeMetrics: DashboardNodeMetrics[], + dashboardNodeMetrics: DashboardNodeRewards[], sx?: SxProps; } @@ -28,17 +28,17 @@ const RewardTable: React.FC = ({ dashboardNodeMetrics }) => { {dashboardNodeMetrics.map((nodeMetrics) => ( - {nodeMetrics.nodeId} + {nodeMetrics.nodeId.toText()} - {Math.round(nodeMetrics.failureRateAvg)}% + {Math.round(nodeMetrics.failureRateAvg * 100)}% - {Math.round(nodeMetrics.rewardsNoPenalty)}% + {Math.round(nodeMetrics.rewardsNoPenalty * 100)}% ))} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx index 57fcfb91f..7283f878c 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -5,12 +5,12 @@ import Divider from '@mui/material/Divider'; import { useParams } from 'react-router-dom'; import { generateChartData, getFormattedDates } from '../utils/utils'; import RewardTable from './RewardTable'; -import { DashboardNodeMetrics } from '../models/NodeMetrics'; +import { DashboardNodeRewards } from '../models/NodeMetrics'; import { PeriodFilter } from './FilterBar'; import { Root } from './NodeList'; export interface SubnetChartProps { - dashboardNodeMetrics: DashboardNodeMetrics[], + dashboardNodeMetrics: DashboardNodeRewards[], periodFilter: PeriodFilter } @@ -18,15 +18,17 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, const [stackOrder] = useState('ascending'); const { subnet } = useParams(); const subnetNodeMetrics = dashboardNodeMetrics - .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnetId === subnet)) + .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnet_id.toText() === subnet)) const chartData = subnetNodeMetrics - .filter((nodeMetrics) => nodeMetrics.dailyData.some(fr => fr.failureRate >= 10)) + .filter((nodeMetrics) => nodeMetrics.dailyData.some(data => data.failure_rate >= 0.1)) .map(nodeMetrics => { return { data: generateChartData(periodFilter, nodeMetrics.dailyData).map(daily => daily.failureRate), - label: nodeMetrics.nodeId, + label: nodeMetrics.nodeId.toText(), } }); + + console.info(chartData) const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; return ( @@ -39,7 +41,7 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, - Daily Failure Rate + Daily Failure Rate (grater 10%) elem.failureRate)); + this.failureRateAvg = computeAverageFailureRate(dailyData.map(elem => elem.failure_rate)); this.rewardsNoPenalty = rewardsNoPenalty; - } -} - -export class DailyNodeMetrics { - nodeId: string; - dailyData: DailyData; - - constructor( - nodeId: string, - dailyData: DailyData - ) { - this.nodeId = nodeId; - this.dailyData = dailyData; + this.rewardsWithPenalty = rewardsWithPenalty; } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx index 4115c2ea0..319ee7d22 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -1,5 +1,6 @@ +import { DailyNodeData } from "../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did"; import { PeriodFilter } from "../components/FilterBar"; -import { ChartData, DailyData, NodeMetrics } from "../models/NodeMetrics"; +import { ChartData } from "../models/NodeMetrics"; export const dateToNanoseconds = (date: Date): bigint => { @@ -8,25 +9,27 @@ export const dateToNanoseconds = (date: Date): bigint => { return nanosecondsSinceEpoch; }; -export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyData[]): ChartData[] => { +export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyNodeData[]): ChartData[] => { const { dateStart, dateEnd } = periodFilter; const chartData: ChartData[] = []; const currentDate = new Date(dateStart); while (currentDate <= dateEnd) { - const dailyDataEntry = dailyData.find(data => - data.date.getFullYear() === currentDate.getFullYear() && - data.date.getMonth() === currentDate.getMonth() && - data.date.getDate() === currentDate.getDate() - ); + const dailyDataEntry = dailyData.find(data => { + const date = new Date(Number(data.ts) / 1000000); + + return date.getFullYear() === currentDate.getFullYear() && + date.getMonth() === currentDate.getMonth() && + date.getDate() === currentDate.getDate() + }); + + chartData.push({ + date: new Date(currentDate), + failureRate: dailyDataEntry ? dailyDataEntry.failure_rate * 100 : null, + }); - chartData.push({ - date: new Date(currentDate), - failureRate: dailyDataEntry ? dailyDataEntry.failureRate : null, - }); - - currentDate.setDate(currentDate.getDate() + 1); + currentDate.setDate(currentDate.getDate() + 1); } return chartData; @@ -48,60 +51,6 @@ export const getFormattedDates = (period: PeriodFilter): string[] => { return dates; }; -export function transformDailyData(data: DailyData[]): { [key: string]: string | number | Date | null | undefined }[] { - return data.map(item => ({ - date: item.date, - subnetId: item.subnetId, - numBlockFailures: item.numBlockFailures, - numBlocksProposed: item.numBlocksProposed, - failureRate: item.failureRate, - })); - } - -export function groupBy(items: T[], key: K): Record { - return items.reduce((result, item) => { - const groupKey = String(item[key]); - if (!result[groupKey]) { - result[groupKey] = []; - } - result[groupKey].push(item); - return result; - }, {} as Record); - } - - - export function calculateDailyValues (items: NodeMetrics[],): DailyData[] { - const dailyValues: DailyData[] = []; - let previousTotals = { failures: 0.0, proposed: 0.0 }; - - items.sort((a, b) => a.date.getTime() - b.date.getTime()); - - for (const item of items) { - const currentDate = item.date; - const currentSubnet = item.subnetId; - const currentTotals = { - failures: Number(item.numBlockFailuresTotal), - proposed: Number(item.numBlocksProposedTotal), - }; - - if (previousTotals.failures || previousTotals.proposed) { - const dailyFailures = currentTotals.failures - previousTotals.failures; - const dailyProposed = currentTotals.proposed - previousTotals.proposed; - - dailyValues.push( new DailyData( - currentDate, - currentSubnet.toText(), - dailyFailures, - dailyProposed, - )); - } - - previousTotals = currentTotals; - } - - return dailyValues; - } - export const computeAverageFailureRate = (data: number[]): number => { if (data.length === 0) return 0; const sum = data.reduce((acc, val) => acc + val, 0); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index efe5fa370..48a32c716 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -67,12 +67,12 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { let period_start = args.from_ts; let period_end = args.to_ts; let metrics = stable_memory::get_metrics_range(period_start, Some(period_end)); - let mut metrics_by_node: collections::BTreeMap> = collections::BTreeMap::new(); + let mut metrics_by_node: collections::BTreeMap> = collections::BTreeMap::new(); for (ts, subnets) in metrics { for subnet_metrics in subnets { for node_metrics in subnet_metrics.node_metrics { - metrics_by_node.entry(node_metrics.node_id).or_default().push((ts, node_metrics)); + metrics_by_node.entry(node_metrics.node_id).or_default().push((ts, node_metrics, subnet_metrics.subnet_id)); } } } @@ -83,9 +83,16 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { let result = metrics_by_node .into_iter() .map(|(node_id, metrics_in_period)| { - let node_rewards = rewards_manager::compute_rewards(metrics_in_period, initial_node_metrics.get(&node_id).cloned().unwrap()); - - NodeRewardsResponse { node_id, node_rewards } + let daily_data = rewards_manager::daily_data(metrics_in_period, initial_node_metrics.get(&node_id).cloned().unwrap()); + let rewards_no_penalty = rewards_manager::rewards_no_penalty(&daily_data); + let rewards_with_penalty = rewards_manager::rewards_with_penalty(&daily_data); + + NodeRewardsResponse { + node_id, + rewards_no_penalty, + rewards_with_penalty, + daily_data + } }) .collect_vec(); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index b30c789a9..b5f3c6f2f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,17 +1,10 @@ -use chrono::{DateTime, Duration, Utc}; +use candid::Principal; +use chrono::{Duration, Utc}; -use crate::types::{NodeMetrics, Rewards, TimestampNanos}; +use crate::types::{DailyNodeData, NodeMetrics, TimestampNanos}; -#[derive(Debug)] -pub struct DailyFailureRate { - pub datetime: DateTime, - pub failure_rate: f64, -} - -impl DailyFailureRate { - pub fn new(ts_nanos: TimestampNanos, proposed_blocks: u64, failed_blocks: u64) -> Self { - let secs = (ts_nanos / 1_000_000_000) as i64; - let nanos = (secs % 1_000_000_000) as u32; +impl DailyNodeData { + pub fn new(ts: TimestampNanos, subnet_id: Principal, proposed_blocks: u64, failed_blocks: u64) -> Self { let total_blocks = failed_blocks + proposed_blocks; let failure_rate = if total_blocks == 0 { 0.0 @@ -19,10 +12,7 @@ impl DailyFailureRate { failed_blocks as f64 / total_blocks as f64 }; - DailyFailureRate { - datetime: chrono::DateTime::::from_timestamp(secs, nanos).unwrap(), - failure_rate, - } + DailyNodeData { ts, subnet_id, failure_rate } } } @@ -39,21 +29,26 @@ fn daily_reduction(failure_rate: &f64) -> f64 { } } -fn calculate_reduction(metrics: &[DailyFailureRate]) -> (f64, f64) { - let active_days = metrics.len(); +fn is_one_day_after(ts1: u64, ts2: u64) -> bool { + let ts1_sec = ts1 / 1_000_000_000; + let ts2_sec = ts2 / 1_000_000_000; + + let dt1 = chrono::DateTime::::from_timestamp(ts1_sec as i64, 0).unwrap(); + let dt2 = chrono::DateTime::::from_timestamp(ts2_sec as i64, 0).unwrap(); + + dt2.date_naive() == dt1.date_naive() - Duration::days(1) +} + +pub fn rewards_with_penalty(daily_data: &[DailyNodeData]) -> f64 { + let active_days = daily_data.len(); - let mut day_tracker = metrics[0].datetime; + let mut previous_ts = daily_data[0].ts; let mut consecutive_days = Vec::new(); let mut reduction_with_penalty = 0 as f64; - let reduction_no_penalty = metrics.iter().fold(0 as f64, |mut acc, daily_metrics| { - acc += daily_reduction(&daily_metrics.failure_rate); - acc - }) / (active_days as f64); - - for daily_metrics in metrics { - let daily_reduction = daily_reduction(&daily_metrics.failure_rate); - let is_day_after = daily_metrics.datetime.date_naive() == day_tracker.date_naive() + Duration::days(1); + for node_data in daily_data { + let daily_reduction = daily_reduction(&node_data.failure_rate); + let is_day_after = is_one_day_after(node_data.ts, previous_ts); if daily_reduction == 0 as f64 { if !consecutive_days.is_empty() { @@ -66,36 +61,51 @@ fn calculate_reduction(metrics: &[DailyFailureRate]) -> (f64, f64) { reduction_with_penalty += daily_reduction } - day_tracker = daily_metrics.datetime; + previous_ts = node_data.ts } reduction_with_penalty /= active_days as f64; - (reduction_no_penalty, reduction_with_penalty) + 1.0 - reduction_with_penalty } -pub fn compute_rewards(mut metrics: Vec<(TimestampNanos, NodeMetrics)>, initial_metrics: NodeMetrics) -> Rewards { - let mut daily_failure_rate = Vec::new(); +pub fn rewards_no_penalty(daily_data: &[DailyNodeData]) -> f64 { + let active_days = daily_data.len(); - metrics.sort_by_key(|&(timestamp, _)| timestamp); + let reduction_no_penalty = daily_data.iter().fold(0 as f64, |mut acc, data| { + acc += daily_reduction(&data.failure_rate); + acc + }) / (active_days as f64); + + 1.0 - reduction_no_penalty +} + +pub fn daily_data(mut metrics: Vec<(TimestampNanos, NodeMetrics, Principal)>, initial_metrics: NodeMetrics) -> Vec { + let mut failure_rates = Vec::new(); + + metrics.sort_by_key(|&(timestamp, _, _)| timestamp); let mut previous_failed_total = initial_metrics.num_block_failures_total; let mut previous_proposed_total = initial_metrics.num_blocks_proposed_total; - for (ts_nanos, node_metrics) in metrics { - let daily_proposed = node_metrics.num_blocks_proposed_total - previous_proposed_total; - let daily_failed = node_metrics.num_block_failures_total - previous_failed_total; + for (ts_nanos, node_metrics, subnet_id) in metrics { + let current_failed_total = node_metrics.num_block_failures_total; + let current_proposed_total = node_metrics.num_blocks_proposed_total; - daily_failure_rate.push(DailyFailureRate::new(ts_nanos, daily_proposed, daily_failed)); + if previous_failed_total > current_failed_total || previous_proposed_total > current_proposed_total { + // This is the case when the machine gets redeployed + previous_failed_total = 0; + previous_proposed_total = 0; + }; - previous_failed_total = node_metrics.num_block_failures_total; - previous_proposed_total = node_metrics.num_blocks_proposed_total; - } + let daily_failed = current_failed_total - previous_failed_total; + let daily_proposed = current_proposed_total - previous_proposed_total; - let (reduction_no_penalty, reduction_with_penalty) = calculate_reduction(&daily_failure_rate); + failure_rates.push(DailyNodeData::new(ts_nanos, subnet_id, daily_proposed, daily_failed)); - Rewards { - rewards_standard: (1.0 - reduction_no_penalty) * 100.0, - rewards_with_penalty: (1.0 - reduction_with_penalty) * 100.0, + previous_failed_total = current_failed_total; + previous_proposed_total = current_proposed_total; } + + failure_rates } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index ee9536c02..c842c7b72 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -36,15 +36,18 @@ pub struct SubnetNodeMetricsArgs { } #[derive(Debug, Deserialize, Serialize, CandidType)] -pub struct Rewards { - pub rewards_standard: f64, - pub rewards_with_penalty: f64, +pub struct DailyNodeData { + pub ts: u64, + pub subnet_id: Principal, + pub failure_rate: f64, } #[derive(Debug, Deserialize, CandidType)] pub struct NodeRewardsResponse { pub node_id: Principal, - pub node_rewards: Rewards, + pub rewards_no_penalty: f64, + pub rewards_with_penalty: f64, + pub daily_data: Vec, } #[derive(Deserialize, CandidType)] diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index affc6ce63..cc127b437 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -21,14 +21,17 @@ type SubnetNodeMetricsArgs = record { ts: opt nat64; }; -type Rewards = record { - rewards_standard: float64; - rewards_with_penalty: float64; +type DailyNodeData = record { + ts: nat64; + subnet_id: principal; + failure_rate: float64; }; type NodeRewardsResponse = record { node_id: principal; - node_rewards: Rewards; + rewards_no_penalty: float64; + rewards_with_penalty: float64; + daily_data: vec DailyNodeData; }; type NodeRewardsArgs = record { From c32f3055a7b250437a933acaf7e4d10231a6a660 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 6 Aug 2024 20:20:17 +0200 Subject: [PATCH 23/40] Add rewards with penalty dashboard --- .../src/components/Gauge.tsx | 6 +++--- .../src/components/NodeList.tsx | 15 +++++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx index c8da66d30..aa294ce32 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx @@ -6,7 +6,7 @@ export default function FailureRateArc(value: number) { return ( - Failure Rate Average + Failure Rate - Node Reward + {title} {FailureRateArc(failureRateAvg)} - {RewardsArc(rewardsNoPenalty)} + {RewardsArc(rewardsNoPenalty, 'Rewards No Penalty')} @@ -111,9 +117,10 @@ export const NodeList: React.FC = ({ dashboardNodeMetrics, period /> - {filteredMetrics.slice(0, 20).map(({ nodeId, dailyData, failureRateAvg, rewardsNoPenalty }, index) => ( + {filteredMetrics.slice(0, 20).map( + ({ nodeId, dailyData, failureRateAvg, rewardsNoPenalty, rewardsWithPenalty }, index) => ( - {renderChart(nodeId, dailyData, failureRateAvg, rewardsNoPenalty, periodFilter)} + {renderChart(nodeId, dailyData, failureRateAvg, rewardsNoPenalty, rewardsWithPenalty, periodFilter)} ))} From efac96f0165a5bb2049483d255668299cd13ee08 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 7 Aug 2024 19:50:59 +0200 Subject: [PATCH 24/40] Add tests --- Cargo.lock | 1 - .../src/App.tsx | 5 +- .../src/components/NodeList.tsx | 5 +- .../src/components/SubnetChart.tsx | 2 +- .../src/models/NodeMetrics.tsx | 6 +- .../src/utils/utils.tsx | 4 +- .../src/trustworthy-node-metrics/Cargo.toml | 1 - .../src/trustworthy-node-metrics/src/lib.rs | 15 +- .../src/rewards_manager.rs | 200 +++++++++++++----- .../src/trustworthy-node-metrics/src/types.rs | 7 +- .../trustworthy-node-metrics.did | 7 +- 11 files changed, 171 insertions(+), 82 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01d4e9cc6..a17fdbaf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9168,7 +9168,6 @@ dependencies = [ "anyhow", "canbench-rs", "candid", - "chrono", "ciborium", "dfn_core", "futures", diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index b01665c0b..f4bafb892 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -54,7 +54,6 @@ function App() { const updateRewards = async () => { try { setIsLoading(true) - const c = periodFilter.dateStart.setHours(0, 0, 0, 0); const request: NodeRewardsArgs = { from_ts: dateToNanoseconds(periodFilter.dateStart), to_ts: dateToNanoseconds(periodFilter.dateEnd), @@ -64,14 +63,14 @@ function App() { const dashboardNodeRewards = nodeRewardsResponse.map((nodeRewards) => { return new DashboardNodeRewards( nodeRewards.node_id, - nodeRewards.daily_data, + nodeRewards.daily_metrics, nodeRewards.rewards_no_penalty, nodeRewards.rewards_with_penalty, ); }).sort((a, b) => a.rewardsNoPenalty - b.rewardsNoPenalty ); - const subnets = new Set(dashboardNodeRewards.flatMap(nodeRewards => nodeRewards.dailyData.map( data => data.subnet_id.toText()))); + const subnets = new Set(dashboardNodeRewards.flatMap(nodeRewards => nodeRewards.dailyData.map( data => data.subnet_assigned.toText()))); setDashboardNodeRewards(dashboardNodeRewards); setSubnets(subnets); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index aaadabc98..9ff1a1b40 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -8,7 +8,7 @@ import { PeriodFilter } from './FilterBar'; import { generateChartData} from '../utils/utils'; import FailureRateArc, { RewardsArc } from './Gauge'; import { Principal } from '@dfinity/principal'; -import { DailyNodeData } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; +import { DailyMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; export const Root = styled('div')(({ theme }) => ({ width: '100%', @@ -26,7 +26,7 @@ export interface NodeListProps { function renderChart( nodeId: Principal, - dailyData: DailyNodeData[], + dailyData: DailyMetrics[], failureRateAvg: number, rewardsNoPenalty: number, rewardsWithPenalty: number, @@ -43,6 +43,7 @@ function renderChart( {FailureRateArc(failureRateAvg)} {RewardsArc(rewardsNoPenalty, 'Rewards No Penalty')} + {RewardsArc(rewardsWithPenalty, 'Rewards With Penalty')} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx index 7283f878c..c50310be2 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -18,7 +18,7 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, const [stackOrder] = useState('ascending'); const { subnet } = useParams(); const subnetNodeMetrics = dashboardNodeMetrics - .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnet_id.toText() === subnet)) + .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnet_assigned.toText() === subnet)) const chartData = subnetNodeMetrics .filter((nodeMetrics) => nodeMetrics.dailyData.some(data => data.failure_rate >= 0.1)) .map(nodeMetrics => { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx index c71704f4c..cab141cbe 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -1,5 +1,5 @@ +import { DailyMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; import { computeAverageFailureRate } from '../utils/utils'; -import { DailyNodeData } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; import { Principal } from '@dfinity/principal'; export interface ChartData { date: Date ; @@ -9,14 +9,14 @@ export interface ChartData { export class DashboardNodeRewards { nodeId: Principal; nodeIdSmall: string; - dailyData: DailyNodeData[]; + dailyData: DailyMetrics[]; failureRateAvg: number; rewardsNoPenalty: number; rewardsWithPenalty: number; constructor( nodeId: Principal, - dailyData: DailyNodeData[], + dailyData: DailyMetrics[], rewardsNoPenalty: number, rewardsWithPenalty: number, ) { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx index 319ee7d22..6e694439f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -1,4 +1,4 @@ -import { DailyNodeData } from "../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did"; +import { DailyMetrics } from "../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did"; import { PeriodFilter } from "../components/FilterBar"; import { ChartData } from "../models/NodeMetrics"; @@ -9,7 +9,7 @@ export const dateToNanoseconds = (date: Date): bigint => { return nanosecondsSinceEpoch; }; -export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyNodeData[]): ChartData[] => { +export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyMetrics[]): ChartData[] => { const { dateStart, dateEnd } = periodFilter; const chartData: ChartData[] = []; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml index 9122107da..dd4c49695 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml @@ -33,4 +33,3 @@ ic-nns-common = { workspace = true } ic-registry-transport = { workspace = true } dfn_core = { workspace = true } canbench-rs = { version = "0.1.4", optional = true } -chrono = { version = "0.4", default-features = false, features = ["serde"] } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 48a32c716..3462ee9ae 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -72,7 +72,10 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { for (ts, subnets) in metrics { for subnet_metrics in subnets { for node_metrics in subnet_metrics.node_metrics { - metrics_by_node.entry(node_metrics.node_id).or_default().push((ts, node_metrics, subnet_metrics.subnet_id)); + metrics_by_node + .entry(node_metrics.node_id) + .or_default() + .push((ts, node_metrics, subnet_metrics.subnet_id)); } } } @@ -83,15 +86,15 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { let result = metrics_by_node .into_iter() .map(|(node_id, metrics_in_period)| { - let daily_data = rewards_manager::daily_data(metrics_in_period, initial_node_metrics.get(&node_id).cloned().unwrap()); - let rewards_no_penalty = rewards_manager::rewards_no_penalty(&daily_data); - let rewards_with_penalty = rewards_manager::rewards_with_penalty(&daily_data); + let daily_metrics = rewards_manager::daily_metrics(metrics_in_period, initial_node_metrics.get(&node_id).cloned().unwrap()); + let rewards_no_penalty = rewards_manager::rewards_no_penalty(&daily_metrics); + let rewards_with_penalty = rewards_manager::rewards_with_penalty(&daily_metrics); - NodeRewardsResponse { + NodeRewardsResponse { node_id, rewards_no_penalty, rewards_with_penalty, - daily_data + daily_metrics, } }) .collect_vec(); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index b5f3c6f2f..ce8387cc6 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,94 +1,98 @@ use candid::Principal; -use chrono::{Duration, Utc}; -use crate::types::{DailyNodeData, NodeMetrics, TimestampNanos}; - -impl DailyNodeData { - pub fn new(ts: TimestampNanos, subnet_id: Principal, proposed_blocks: u64, failed_blocks: u64) -> Self { - let total_blocks = failed_blocks + proposed_blocks; - let failure_rate = if total_blocks == 0 { - 0.0 - } else { - failed_blocks as f64 / total_blocks as f64 - }; - - DailyNodeData { ts, subnet_id, failure_rate } - } -} +use crate::types::{DailyMetrics, NodeMetrics, TimestampNanos}; const MIN_FAILURE_RATE: f64 = 0.1; const MAX_FAILURE_RATE: f64 = 0.7; -fn daily_reduction(failure_rate: &f64) -> f64 { +fn daily_rewards_reduction(failure_rate: &f64) -> f64 { if failure_rate < &MIN_FAILURE_RATE { 0.0 } else if failure_rate > &MAX_FAILURE_RATE { 1.0 } else { - (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) + let reduction = (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE); + (reduction * 100.0).round() / 100.0 } } -fn is_one_day_after(ts1: u64, ts2: u64) -> bool { - let ts1_sec = ts1 / 1_000_000_000; - let ts2_sec = ts2 / 1_000_000_000; - - let dt1 = chrono::DateTime::::from_timestamp(ts1_sec as i64, 0).unwrap(); - let dt2 = chrono::DateTime::::from_timestamp(ts2_sec as i64, 0).unwrap(); - - dt2.date_naive() == dt1.date_naive() - Duration::days(1) +impl DailyMetrics { + pub fn new(ts: TimestampNanos, subnet_assignment: Principal, proposed_blocks: u64, failed_blocks: u64) -> Self { + let total_blocks = failed_blocks + proposed_blocks; + let failure_rate = if total_blocks == 0 { + 0.0 + } else { + failed_blocks as f64 / total_blocks as f64 + }; + + let rewards_reduction = daily_rewards_reduction(&failure_rate); + + DailyMetrics { + ts, + subnet_assigned: subnet_assignment, + failure_rate, + rewards_reduction, + } + } } -pub fn rewards_with_penalty(daily_data: &[DailyNodeData]) -> f64 { - let active_days = daily_data.len(); - - let mut previous_ts = daily_data[0].ts; - let mut consecutive_days = Vec::new(); - let mut reduction_with_penalty = 0 as f64; - - for node_data in daily_data { - let daily_reduction = daily_reduction(&node_data.failure_rate); - let is_day_after = is_one_day_after(node_data.ts, previous_ts); - - if daily_reduction == 0 as f64 { - if !consecutive_days.is_empty() { - reduction_with_penalty += consecutive_days.len() as f64 * consecutive_days.iter().sum::(); - consecutive_days.clear(); +pub fn rewards_with_penalty(daily_metrics: &[DailyMetrics]) -> f64 { + let active_days = daily_metrics.len(); + let mut reduction = 0.0; + let mut consecutive_reduction = 0.0; + let mut consecutive_count = 0; + + for metrics in daily_metrics.iter() { + // Just if we want to count the day unassigned as 0.0 reduction + // we would need to check if previous daily metrics is <= 24hrs + // before current metrics + let daily_rewards: f64 = metrics.rewards_reduction; + + if daily_rewards == 0.0 { + if consecutive_count > 0 { + reduction += consecutive_reduction * consecutive_count as f64; + consecutive_reduction = 0.0; + consecutive_count = 0; } - } else if is_day_after { - consecutive_days.push(daily_reduction) } else { - reduction_with_penalty += daily_reduction + consecutive_reduction += daily_rewards; + consecutive_count += 1; } - - previous_ts = node_data.ts + } + + // Handles the last consecutive days + if consecutive_count > 0 { + reduction += consecutive_reduction * consecutive_count as f64; } - reduction_with_penalty /= active_days as f64; - - 1.0 - reduction_with_penalty + reduction /= active_days as f64; + let reduction_normalized = reduction.min(1.0); + + ((1.0 - reduction_normalized) * 100.0).round() / 100.0 } -pub fn rewards_no_penalty(daily_data: &[DailyNodeData]) -> f64 { - let active_days = daily_data.len(); +pub fn rewards_no_penalty(daily_metrics: &[DailyMetrics]) -> f64 { + let active_days = daily_metrics.len(); - let reduction_no_penalty = daily_data.iter().fold(0 as f64, |mut acc, data| { - acc += daily_reduction(&data.failure_rate); + let reduction = daily_metrics.iter().fold(0.0, |mut acc, metrics| { + let daily_rewards = metrics.rewards_reduction; + + acc += daily_rewards; acc }) / (active_days as f64); - 1.0 - reduction_no_penalty + ((1.0 - reduction) * 100.0).round() / 100.0 } -pub fn daily_data(mut metrics: Vec<(TimestampNanos, NodeMetrics, Principal)>, initial_metrics: NodeMetrics) -> Vec { +pub fn daily_metrics(mut node_metrics: Vec<(TimestampNanos, NodeMetrics, Principal)>, initial_metrics: NodeMetrics) -> Vec { let mut failure_rates = Vec::new(); - metrics.sort_by_key(|&(timestamp, _, _)| timestamp); + node_metrics.sort_by_key(|&(timestamp, _, _)| timestamp); let mut previous_failed_total = initial_metrics.num_block_failures_total; let mut previous_proposed_total = initial_metrics.num_blocks_proposed_total; - for (ts_nanos, node_metrics, subnet_id) in metrics { + for (ts_nanos, node_metrics, subnet_id) in node_metrics { let current_failed_total = node_metrics.num_block_failures_total; let current_proposed_total = node_metrics.num_blocks_proposed_total; @@ -101,7 +105,7 @@ pub fn daily_data(mut metrics: Vec<(TimestampNanos, NodeMetrics, Principal)>, in let daily_failed = current_failed_total - previous_failed_total; let daily_proposed = current_proposed_total - previous_proposed_total; - failure_rates.push(DailyNodeData::new(ts_nanos, subnet_id, daily_proposed, daily_failed)); + failure_rates.push(DailyMetrics::new(ts_nanos, subnet_id, daily_proposed, daily_failed)); previous_failed_total = current_failed_total; previous_proposed_total = current_proposed_total; @@ -109,3 +113,85 @@ pub fn daily_data(mut metrics: Vec<(TimestampNanos, NodeMetrics, Principal)>, in failure_rates } + +#[cfg(test)] +mod tests { + use itertools::Itertools; + + use super::*; + + struct MockedMetrics { + days: u64, + proposed_blocks: u64, + failed_blocks: u64, + } + + impl MockedMetrics { + fn new(days: u64, proposed_blocks: u64, failed_blocks: u64) -> Self { + MockedMetrics { + days, + proposed_blocks, + failed_blocks, + } + } + } + + fn daily_mocked_metrics(metrics: Vec) -> Vec { + let subnet = Principal::anonymous(); + let mut i = 0; + + metrics.into_iter().flat_map(|mocked_metrics: MockedMetrics| + (0..mocked_metrics.days).map(move |_| { + let next_ts = i * 24 * 60 * 60 * 1_000_000_000; + i += 1; + DailyMetrics::new(next_ts, subnet, mocked_metrics.proposed_blocks, mocked_metrics.failed_blocks) + }) + ).collect_vec() + } + + #[test] + fn test_rewards_no_penalty() { + let metrics: Vec = vec![ + MockedMetrics::new(10, 6, 4) + ]; + + let daily_metrics = daily_mocked_metrics(metrics); + let no_penalty = rewards_no_penalty(&daily_metrics); + assert_eq!(no_penalty, 0.5); + } + + #[test] + fn test_rewards_with_penalty() { + let metrics: Vec = vec![ + MockedMetrics::new(5, 6, 4), + MockedMetrics::new(25, 10, 0), + ]; + + let daily_metrics = daily_mocked_metrics(metrics); + let with_penalty = rewards_with_penalty(&daily_metrics); + assert_eq!(with_penalty, 0.58); + } + + #[test] + fn test_rewards_with_penalty_min_0() { + let metrics: Vec = vec![ + MockedMetrics::new(5, 6, 4) + ]; + + let daily_metrics = daily_mocked_metrics(metrics); + let with_penalty = rewards_with_penalty(&daily_metrics); + assert_eq!(with_penalty, 0.0); + } + + #[test] + fn test_rewards_with_penalty_2_days() { + let metrics: Vec = vec![ + MockedMetrics::new(5, 6, 4) + ]; + + let daily_metrics = daily_mocked_metrics(metrics); + let with_penalty = rewards_with_penalty(&daily_metrics); + assert_eq!(with_penalty, 0.0); + } + +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index c842c7b72..a54b548d2 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -36,10 +36,11 @@ pub struct SubnetNodeMetricsArgs { } #[derive(Debug, Deserialize, Serialize, CandidType)] -pub struct DailyNodeData { +pub struct DailyMetrics { pub ts: u64, - pub subnet_id: Principal, + pub subnet_assigned: Principal, pub failure_rate: f64, + pub rewards_reduction: f64, } #[derive(Debug, Deserialize, CandidType)] @@ -47,7 +48,7 @@ pub struct NodeRewardsResponse { pub node_id: Principal, pub rewards_no_penalty: f64, pub rewards_with_penalty: f64, - pub daily_data: Vec, + pub daily_metrics: Vec, } #[derive(Deserialize, CandidType)] diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index cc127b437..e4ddbf205 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -21,17 +21,18 @@ type SubnetNodeMetricsArgs = record { ts: opt nat64; }; -type DailyNodeData = record { +type DailyMetrics = record { ts: nat64; - subnet_id: principal; + subnet_assigned: principal; failure_rate: float64; + rewards_reduction: float64; }; type NodeRewardsResponse = record { node_id: principal; rewards_no_penalty: float64; rewards_with_penalty: float64; - daily_data: vec DailyNodeData; + daily_metrics: vec DailyMetrics; }; type NodeRewardsArgs = record { From 332cd1d050091bd1aec945a0e36ba980ad75fcc9 Mon Sep 17 00:00:00 2001 From: Pietro Date: Fri, 9 Aug 2024 20:37:09 +0200 Subject: [PATCH 25/40] Add node rewards metrics --- .../src/App.tsx | 2 +- .../src/components/NodeList.tsx | 4 +- .../src/models/NodeMetrics.tsx | 6 +- .../src/utils/utils.tsx | 4 +- .../src/trustworthy-node-metrics/src/lib.rs | 99 +++++--- .../src/metrics_manager.rs | 79 +++--- .../src/rewards_manager.rs | 229 ++++++++++++------ .../src/stable_memory.rs | 85 +++---- .../src/trustworthy-node-metrics/src/types.rs | 50 ++-- .../trustworthy-node-metrics.did | 8 +- 10 files changed, 335 insertions(+), 231 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index f4bafb892..6043cf723 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -63,7 +63,7 @@ function App() { const dashboardNodeRewards = nodeRewardsResponse.map((nodeRewards) => { return new DashboardNodeRewards( nodeRewards.node_id, - nodeRewards.daily_metrics, + nodeRewards.daily_node_metrics, nodeRewards.rewards_no_penalty, nodeRewards.rewards_with_penalty, ); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index 9ff1a1b40..348e43e29 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -8,7 +8,7 @@ import { PeriodFilter } from './FilterBar'; import { generateChartData} from '../utils/utils'; import FailureRateArc, { RewardsArc } from './Gauge'; import { Principal } from '@dfinity/principal'; -import { DailyMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; +import { DailyNodeMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; export const Root = styled('div')(({ theme }) => ({ width: '100%', @@ -26,7 +26,7 @@ export interface NodeListProps { function renderChart( nodeId: Principal, - dailyData: DailyMetrics[], + dailyData: DailyNodeMetrics[], failureRateAvg: number, rewardsNoPenalty: number, rewardsWithPenalty: number, diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx index cab141cbe..e7e910e6f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx @@ -1,4 +1,4 @@ -import { DailyMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; +import { DailyNodeMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; import { computeAverageFailureRate } from '../utils/utils'; import { Principal } from '@dfinity/principal'; export interface ChartData { @@ -9,14 +9,14 @@ export interface ChartData { export class DashboardNodeRewards { nodeId: Principal; nodeIdSmall: string; - dailyData: DailyMetrics[]; + dailyData: DailyNodeMetrics[]; failureRateAvg: number; rewardsNoPenalty: number; rewardsWithPenalty: number; constructor( nodeId: Principal, - dailyData: DailyMetrics[], + dailyData: DailyNodeMetrics[], rewardsNoPenalty: number, rewardsWithPenalty: number, ) { diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx index 6e694439f..b62c59fd0 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -1,4 +1,4 @@ -import { DailyMetrics } from "../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did"; +import { DailyNodeMetrics } from "../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did"; import { PeriodFilter } from "../components/FilterBar"; import { ChartData } from "../models/NodeMetrics"; @@ -9,7 +9,7 @@ export const dateToNanoseconds = (date: Date): bigint => { return nanosecondsSinceEpoch; }; -export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyMetrics[]): ChartData[] => { +export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyNodeMetrics[]): ChartData[] => { const { dateStart, dateEnd } = periodFilter; const chartData: ChartData[] = []; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 3462ee9ae..808c18e20 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -1,8 +1,14 @@ use candid::Principal; use ic_cdk_macros::*; use itertools::Itertools; -use std::{collections, time::Duration}; -use types::{NodeMetrics, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, SubnetNodeMetricsResponse, TimestampNanos}; +use std::{ + collections::{self, btree_map::Entry, BTreeMap}, + time::Duration, +}; +use types::{ + DailyNodeMetrics, NodeMetrics, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, + SubnetNodeMetricsResponse +}; mod metrics_manager; mod rewards_manager; mod stable_memory; @@ -40,25 +46,40 @@ fn post_upgrade() { #[query] fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result, String> { let from_ts = args.ts.unwrap_or_default(); + let mut subnet_node_metrics: BTreeMap<(u64, Principal), Vec> = BTreeMap::new(); - let metrics = stable_memory::get_metrics_range(from_ts, None); + let node_metrics: Vec<(NodeMetricsStoredKey, types::NodeMetricsStored)> = stable_memory::get_metrics_range(from_ts, None); - let metrics_flat = metrics + for ((ts, node_id), node_metrics_value) in node_metrics { + if let Some(subnet_id) = args.subnet_id { + if subnet_id != node_metrics_value.subnet_assigned { + continue; + } + } + + let result_key = (ts, node_metrics_value.subnet_assigned); + let result_value: NodeMetrics = NodeMetrics { + node_id, + num_blocks_proposed_total: node_metrics_value.num_blocks_proposed_total, + num_blocks_failures_total: node_metrics_value.num_blocks_failures_total, + }; + + match subnet_node_metrics.entry(result_key) { + Entry::Occupied(mut entry) => { + let v: &mut Vec = entry.get_mut(); + v.push(result_value) + } + Entry::Vacant(entry) => { + entry.insert(vec![result_value]); + } + } + } + + let result = subnet_node_metrics .into_iter() - .flat_map(|(ts, subnets)| { - subnets.into_iter().map(move |subnet_node_metrics| SubnetNodeMetricsResponse { - ts, - subnet_id: subnet_node_metrics.subnet_id, - node_metrics: subnet_node_metrics.node_metrics, - }) - }) + .map(|((ts, subnet_id), node_metrics)| SubnetNodeMetricsResponse { ts, subnet_id, node_metrics }) .collect_vec(); - let result = match args.subnet_id { - Some(subnet_id) => metrics_flat.into_iter().filter(|metrics| metrics.subnet_id == subnet_id).collect_vec(), - None => metrics_flat, - }; - Ok(result) } @@ -66,38 +87,40 @@ fn subnet_node_metrics(args: SubnetNodeMetricsArgs) -> Result Vec { let period_start = args.from_ts; let period_end = args.to_ts; - let metrics = stable_memory::get_metrics_range(period_start, Some(period_end)); - let mut metrics_by_node: collections::BTreeMap> = collections::BTreeMap::new(); - - for (ts, subnets) in metrics { - for subnet_metrics in subnets { - for node_metrics in subnet_metrics.node_metrics { - metrics_by_node - .entry(node_metrics.node_id) - .or_default() - .push((ts, node_metrics, subnet_metrics.subnet_id)); + let node_metrics: Vec<(NodeMetricsStoredKey, types::NodeMetricsStored)> = stable_memory::get_metrics_range(period_start, Some(period_end)); + + let mut daily_metrics = collections::BTreeMap::new(); + for ((ts, node_id), node_metrics_value) in node_metrics { + let daily_node_metrics = DailyNodeMetrics::new( + ts, + node_metrics_value.subnet_assigned, + node_metrics_value.num_blocks_proposed, + node_metrics_value.num_blocks_failed, + ); + + match daily_metrics.entry(node_id) { + Entry::Occupied(mut entry) => { + let v: &mut Vec = entry.get_mut(); + v.push(daily_node_metrics) + } + Entry::Vacant(entry) => { + entry.insert(vec![daily_node_metrics]); } } } - let node_ids = metrics_by_node.keys().cloned().collect_vec(); - let initial_node_metrics = stable_memory::metrics_before_ts(node_ids, &period_start); - - let result = metrics_by_node + daily_metrics .into_iter() - .map(|(node_id, metrics_in_period)| { - let daily_metrics = rewards_manager::daily_metrics(metrics_in_period, initial_node_metrics.get(&node_id).cloned().unwrap()); - let rewards_no_penalty = rewards_manager::rewards_no_penalty(&daily_metrics); - let rewards_with_penalty = rewards_manager::rewards_with_penalty(&daily_metrics); + .map(|(node_id, daily_node_metrics)| { + let rewards_no_penalty = rewards_manager::rewards_no_penalty(&daily_node_metrics); + let rewards_with_penalty = rewards_manager::rewards_with_penalty(&daily_node_metrics); NodeRewardsResponse { node_id, rewards_no_penalty, rewards_with_penalty, - daily_metrics, + daily_node_metrics, } }) - .collect_vec(); - - result + .collect_vec() } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs index 5f638375e..ca64c6869 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs @@ -1,65 +1,72 @@ -use std::collections::{btree_map::Entry, BTreeMap}; +use std::collections::BTreeMap; use anyhow::Ok; use dfn_core::api::PrincipalId; use futures::FutureExt; -use ic_management_canister_types::NodeMetrics as ICManagementNodeMetrics; use ic_management_canister_types::{NodeMetricsHistoryArgs, NodeMetricsHistoryResponse}; use ic_protobuf::registry::subnet::v1::SubnetListRecord; -use itertools::Itertools; +use crate::types::{NodeMetricsStored, NodeMetricsStoredKey}; use crate::{ stable_memory, - types::{NodeMetrics, PrincipalNodeMetricsHistory, SubnetNodeMetrics, TimestampNanos}, + types::{PrincipalNodeMetricsHistory, TimestampNanos}, }; -impl SubnetNodeMetrics { - pub fn new(subnet_id: PrincipalId, subnet_metrics: Vec) -> Self { - let node_metrics = subnet_metrics.into_iter().map(|node_metrics| node_metrics.into()).collect_vec(); - - Self { - subnet_id: subnet_id.0, - node_metrics, - } +fn store_results(results: BTreeMap) { + for (timestamp, storable) in results { + stable_memory::insert(timestamp, storable) } } -impl From for NodeMetrics { - fn from(node_metrics: ICManagementNodeMetrics) -> Self { - Self { - node_id: node_metrics.node_id.0, - num_block_failures_total: node_metrics.num_block_failures_total, - num_blocks_proposed_total: node_metrics.num_blocks_proposed_total, +fn get_daily_proposed_failed(new_node_metrics: &ic_management_canister_types::NodeMetrics) -> (u64, u64) { + let principal = new_node_metrics.node_id.0; + let existing_metrics = stable_memory::latest_metrics(principal); + let new_failed_total = new_node_metrics.num_block_failures_total; + let new_proposed_total = new_node_metrics.num_blocks_proposed_total; + + let (num_blocks_proposed, num_blocks_failed) = match existing_metrics { + Some(existing_metrics_value) => { + let existing_failed_total = existing_metrics_value.num_blocks_failures_total; + let existing_proposed_total = existing_metrics_value.num_blocks_proposed_total; + + if existing_failed_total > new_failed_total || existing_proposed_total > new_proposed_total { + // This is the case when the node gets redeployed + (new_proposed_total, new_failed_total) + } else { + (new_proposed_total - existing_proposed_total, new_failed_total - existing_failed_total) + } } - } -} + None => (new_proposed_total, new_failed_total), + }; -fn store_results(results: BTreeMap>) { - for (timestamp, storable) in results { - stable_memory::insert(timestamp, storable) - } + (num_blocks_proposed, num_blocks_failed) } /// Transform metrics /// /// Groups the metrics received by timestamp to fit the "storable" format -fn transform_metrics(subnets_metrics: Vec) -> BTreeMap> { +fn transform_metrics(subnets_metrics: Vec) -> BTreeMap { let mut results = BTreeMap::new(); - for (subnet, subnet_metrics) in subnets_metrics { + for (subnet_id, subnet_metrics) in subnets_metrics { for ts_node_metrics in subnet_metrics { let ts: TimestampNanos = ts_node_metrics.timestamp_nanos; - let subnet_metrics_storable = SubnetNodeMetrics::new(subnet, ts_node_metrics.node_metrics); + for node_metrics in ts_node_metrics.node_metrics { + let principal = node_metrics.node_id.0; + let node_metrics_key = (ts, principal); + + let (new_blocks_proposed, new_blocks_failed) = get_daily_proposed_failed(&node_metrics); + + let node_metrics_value = NodeMetricsStored { + subnet_assigned: subnet_id.0, + num_blocks_proposed_total: node_metrics.num_blocks_proposed_total, + num_blocks_failures_total: node_metrics.num_block_failures_total, + num_blocks_proposed: new_blocks_proposed, + num_blocks_failed: new_blocks_failed, + }; - match results.entry(ts) { - Entry::Occupied(mut entry) => { - let v: &mut Vec = entry.get_mut(); - v.push(subnet_metrics_storable) - } - Entry::Vacant(entry) => { - entry.insert(vec![subnet_metrics_storable]); - } + results.insert(node_metrics_key, node_metrics_value); } } } @@ -119,7 +126,7 @@ async fn fetch_subnets() -> anyhow::Result> { pub async fn update_metrics() -> anyhow::Result<()> { let subnets = fetch_subnets().await?; - let latest_ts = stable_memory::latest_key().unwrap_or_default(); + let latest_ts = stable_memory::latest_ts().unwrap_or_default(); let refresh_ts = latest_ts + 1; ic_cdk::println!( diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index ce8387cc6..cccb6ef09 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,6 +1,6 @@ use candid::Principal; -use crate::types::{DailyMetrics, NodeMetrics, TimestampNanos}; +use crate::types::{DailyNodeMetrics, TimestampNanos}; const MIN_FAILURE_RATE: f64 = 0.1; const MAX_FAILURE_RATE: f64 = 0.7; @@ -11,12 +11,11 @@ fn daily_rewards_reduction(failure_rate: &f64) -> f64 { } else if failure_rate > &MAX_FAILURE_RATE { 1.0 } else { - let reduction = (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE); - (reduction * 100.0).round() / 100.0 + (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) } } -impl DailyMetrics { +impl DailyNodeMetrics { pub fn new(ts: TimestampNanos, subnet_assignment: Principal, proposed_blocks: u64, failed_blocks: u64) -> Self { let total_blocks = failed_blocks + proposed_blocks; let failure_rate = if total_blocks == 0 { @@ -24,19 +23,21 @@ impl DailyMetrics { } else { failed_blocks as f64 / total_blocks as f64 }; - + let rewards_reduction = daily_rewards_reduction(&failure_rate); - DailyMetrics { + DailyNodeMetrics { ts, subnet_assigned: subnet_assignment, + num_blocks_proposed: proposed_blocks, + num_blocks_failed: failed_blocks, failure_rate, rewards_reduction, } } } -pub fn rewards_with_penalty(daily_metrics: &[DailyMetrics]) -> f64 { +pub fn rewards_with_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { let active_days = daily_metrics.len(); let mut reduction = 0.0; let mut consecutive_reduction = 0.0; @@ -47,7 +48,7 @@ pub fn rewards_with_penalty(daily_metrics: &[DailyMetrics]) -> f64 { // we would need to check if previous daily metrics is <= 24hrs // before current metrics let daily_rewards: f64 = metrics.rewards_reduction; - + if daily_rewards == 0.0 { if consecutive_count > 0 { reduction += consecutive_reduction * consecutive_count as f64; @@ -56,10 +57,10 @@ pub fn rewards_with_penalty(daily_metrics: &[DailyMetrics]) -> f64 { } } else { consecutive_reduction += daily_rewards; - consecutive_count += 1; + consecutive_count += 1; } } - + // Handles the last consecutive days if consecutive_count > 0 { reduction += consecutive_reduction * consecutive_count as f64; @@ -67,11 +68,11 @@ pub fn rewards_with_penalty(daily_metrics: &[DailyMetrics]) -> f64 { reduction /= active_days as f64; let reduction_normalized = reduction.min(1.0); - + ((1.0 - reduction_normalized) * 100.0).round() / 100.0 } -pub fn rewards_no_penalty(daily_metrics: &[DailyMetrics]) -> f64 { +pub fn rewards_no_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { let active_days = daily_metrics.len(); let reduction = daily_metrics.iter().fold(0.0, |mut acc, metrics| { @@ -84,42 +85,13 @@ pub fn rewards_no_penalty(daily_metrics: &[DailyMetrics]) -> f64 { ((1.0 - reduction) * 100.0).round() / 100.0 } -pub fn daily_metrics(mut node_metrics: Vec<(TimestampNanos, NodeMetrics, Principal)>, initial_metrics: NodeMetrics) -> Vec { - let mut failure_rates = Vec::new(); - - node_metrics.sort_by_key(|&(timestamp, _, _)| timestamp); - - let mut previous_failed_total = initial_metrics.num_block_failures_total; - let mut previous_proposed_total = initial_metrics.num_blocks_proposed_total; - - for (ts_nanos, node_metrics, subnet_id) in node_metrics { - let current_failed_total = node_metrics.num_block_failures_total; - let current_proposed_total = node_metrics.num_blocks_proposed_total; - - if previous_failed_total > current_failed_total || previous_proposed_total > current_proposed_total { - // This is the case when the machine gets redeployed - previous_failed_total = 0; - previous_proposed_total = 0; - }; - - let daily_failed = current_failed_total - previous_failed_total; - let daily_proposed = current_proposed_total - previous_proposed_total; - - failure_rates.push(DailyMetrics::new(ts_nanos, subnet_id, daily_proposed, daily_failed)); - - previous_failed_total = current_failed_total; - previous_proposed_total = current_proposed_total; - } - - failure_rates -} - #[cfg(test)] mod tests { use itertools::Itertools; use super::*; + #[derive(Clone)] struct MockedMetrics { days: u64, proposed_blocks: u64, @@ -136,62 +108,165 @@ mod tests { } } - fn daily_mocked_metrics(metrics: Vec) -> Vec { + fn daily_mocked_metrics(metrics: Vec) -> Vec { let subnet = Principal::anonymous(); let mut i = 0; - metrics.into_iter().flat_map(|mocked_metrics: MockedMetrics| - (0..mocked_metrics.days).map(move |_| { - let next_ts = i * 24 * 60 * 60 * 1_000_000_000; - i += 1; - DailyMetrics::new(next_ts, subnet, mocked_metrics.proposed_blocks, mocked_metrics.failed_blocks) + metrics + .into_iter() + .flat_map(|mocked_metrics: MockedMetrics| { + (0..mocked_metrics.days).map(move |_| { + i += 1; + DailyNodeMetrics::new(i, subnet, mocked_metrics.proposed_blocks, mocked_metrics.failed_blocks) + }) }) - ).collect_vec() + .collect_vec() } #[test] fn test_rewards_no_penalty() { - let metrics: Vec = vec![ - MockedMetrics::new(10, 6, 4) - ]; - - let daily_metrics = daily_mocked_metrics(metrics); - let no_penalty = rewards_no_penalty(&daily_metrics); - assert_eq!(no_penalty, 0.5); + // Failure Rate = 40% Rewards reduction = 50% + // 0.5 * 5 days / 30 days = 0.08 -> Rewards 0.92 + let daily_metrics: Vec = daily_mocked_metrics(vec![MockedMetrics::new(5, 6, 4), MockedMetrics::new(25, 10, 0)]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 0.92); + + // Failure Rate = 40% Rewards reduction = 50% + // 0.5 / 2 days = 0.25 -> Rewards 0.75 + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(1, 6, 4), + MockedMetrics::new(1, 91, 9), // no penalty + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 0.75); + + // Failure Rate = 40% Rewards reduction = 50% 10 days + // Failure Rate = 30% Rewards reduction = 33% + // (0.5 * 10 + 0.33) / 11 = 0.48 Rewards 0.67 + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(1, 7, 3), // no penalty + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 0.67); } #[test] fn test_rewards_with_penalty() { - let metrics: Vec = vec![ - MockedMetrics::new(5, 6, 4), - MockedMetrics::new(25, 10, 0), - ]; + // Failure Rate = 40% Rewards reduction = 50% + // 0.5 * 5^2 days / 30 days = 0.42 -> Rewards 0.58 + let daily_metrics: Vec = daily_mocked_metrics(vec![MockedMetrics::new(5, 6, 4), MockedMetrics::new(25, 10, 0)]); + let rewards = rewards_with_penalty(&daily_metrics); + assert_eq!(rewards, 0.58); + + // Failure Rate = 40% Rewards reduction = 50% + // 0.5 / 2 days = 0.25 -> Rewards 0.75 + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(1, 6, 4), + MockedMetrics::new(1, 91, 9), // no penalty + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 0.75); + + // Failure Rate = 40% Rewards reduction = 50% 10 days + // Failure Rate = 30% Rewards reduction = 33% + // (0.5 * 10 + 0.33) / 11 -> Reduction 0.48 Rewards 0.67 + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(1, 7, 3), // no penalty + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 0.67); + } - let daily_metrics = daily_mocked_metrics(metrics); - let with_penalty = rewards_with_penalty(&daily_metrics); - assert_eq!(with_penalty, 0.58); + #[test] + fn test_rewards_no_penalty_max_reduction() { + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(10, 5, 95), // max failure rate + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 0.0); } #[test] - fn test_rewards_with_penalty_min_0() { - let metrics: Vec = vec![ - MockedMetrics::new(5, 6, 4) - ]; + fn test_rewards_with_penalty_max_reduction() { + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(1, 9, 91), // max failure rate + ]); + let rewards = rewards_with_penalty(&daily_metrics); + assert_eq!(rewards, 0.0); + } - let daily_metrics = daily_mocked_metrics(metrics); - let with_penalty = rewards_with_penalty(&daily_metrics); - assert_eq!(with_penalty, 0.0); + #[test] + fn test_rewards_no_penalty_min_reduction() { + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(10, 9, 1), // min failure rate + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 1.0); } #[test] - fn test_rewards_with_penalty_2_days() { - let metrics: Vec = vec![ - MockedMetrics::new(5, 6, 4) - ]; + fn test_rewards_with_penalty_min_reduction() { + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(10, 9, 1), // min failure rate + ]); + let rewards = rewards_no_penalty(&daily_metrics); + assert_eq!(rewards, 1.0); + } + + #[test] + fn test_same_rewards_if_gaps_no_penalty() { + let gap = MockedMetrics::new(1, 10, 0); + + let daily_metrics_mid_gap: Vec = + daily_mocked_metrics(vec![MockedMetrics::new(1, 6, 4), gap.clone(), MockedMetrics::new(1, 7, 3)]); + + let daily_metrics_left_gap: Vec = + daily_mocked_metrics(vec![gap.clone(), MockedMetrics::new(1, 6, 4), MockedMetrics::new(1, 7, 3)]); + + let daily_metrics_right_gap: Vec = + daily_mocked_metrics(vec![gap.clone(), MockedMetrics::new(1, 6, 4), MockedMetrics::new(1, 7, 3)]); + + assert_eq!(rewards_no_penalty(&daily_metrics_mid_gap), 0.72); + + assert_eq!(rewards_no_penalty(&daily_metrics_mid_gap), rewards_no_penalty(&daily_metrics_left_gap)); + assert_eq!(rewards_no_penalty(&daily_metrics_right_gap), rewards_no_penalty(&daily_metrics_left_gap)); + } + + #[test] + fn test_less_rewards_if_consecutive_with_penalty() { + let gap = MockedMetrics::new(1, 10, 0); - let daily_metrics = daily_mocked_metrics(metrics); - let with_penalty = rewards_with_penalty(&daily_metrics); - assert_eq!(with_penalty, 0.0); + let daily_metrics_no_gap: Vec = daily_mocked_metrics(vec![MockedMetrics::new(4, 8, 2)]); + + let daily_metrics_with_gap: Vec = daily_mocked_metrics(vec![MockedMetrics::new(2, 8, 2), gap, MockedMetrics::new(2, 8, 2)]); + + assert_eq!(rewards_with_penalty(&daily_metrics_no_gap), 0.33); + + assert!(rewards_with_penalty(&daily_metrics_with_gap) > rewards_with_penalty(&daily_metrics_no_gap)); } + #[test] + fn test_same_rewards_if_reversed() { + let daily_metrics: Vec = daily_mocked_metrics(vec![ + MockedMetrics::new(1, 5, 5), + MockedMetrics::new(5, 6, 4), + MockedMetrics::new(25, 10, 0), + ]); + + let mut daily_metrics_1 = daily_metrics.clone(); + let rewards = rewards_with_penalty(&daily_metrics_1); + daily_metrics_1.reverse(); + let rewards_rev = rewards_with_penalty(&daily_metrics_1); + + assert_eq!(rewards, 0.39); + assert_eq!(rewards_rev, rewards); + + let mut daily_metrics_2 = daily_metrics.clone(); + let rewards = rewards_no_penalty(&daily_metrics_2); + daily_metrics_2.reverse(); + let rewards_rev = rewards_no_penalty(&daily_metrics_2); + + assert_eq!(rewards, 0.9); + assert_eq!(rewards_rev, rewards); + } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index b003f61f3..0fe3de46f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -1,73 +1,64 @@ -use candid::Principal; +use candid::{Decode, Encode, Principal}; use ic_stable_structures::{storable::Bound, Storable}; use ic_stable_structures::{DefaultMemoryImpl, StableBTreeMap}; use itertools::Itertools; use std::borrow::Cow; use std::cell::RefCell; -use std::collections::BTreeMap; +use std::u64; -use crate::types::{NodeMetrics, SubnetNodeMetrics, SubnetNodeMetricsStorable, TimestampNanos}; +use crate::types::{NodeMetricsStoredKey, NodeMetricsStored, TimestampNanos}; -impl Storable for SubnetNodeMetricsStorable { - fn to_bytes(&self) -> Cow<[u8]> { - let mut buf = vec![]; - ciborium::ser::into_writer(self, &mut buf).expect("failed to encode SubnetsMetricsStorable"); - Cow::Owned(buf) +impl Storable for NodeMetricsStored { + fn to_bytes(&self) -> std::borrow::Cow<[u8]> { + Cow::Owned(Encode!(self).unwrap()) } - fn from_bytes(bytes: Cow<'_, [u8]>) -> Self { - ciborium::de::from_reader(&bytes[..]).expect("failed to decode SubnetsMetricsStorable") + fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Self { + Decode!(bytes.as_ref(), Self).unwrap() } const BOUND: Bound = Bound::Unbounded; } thread_local! { - pub static MAP: RefCell> = + pub static MAP: RefCell> = RefCell::new(StableBTreeMap::init(DefaultMemoryImpl::default())); } -pub fn insert(key: TimestampNanos, value: Vec) { - MAP.with(|p| p.borrow_mut().insert(key, SubnetNodeMetricsStorable(value))); +pub fn insert(key: NodeMetricsStoredKey, value: NodeMetricsStored) { + MAP.with(|p| p.borrow_mut().insert(key, value)); } -pub fn latest_key() -> Option { - MAP.with(|p| p.borrow().last_key_value()).map(|(k, _)| k) +pub fn latest_ts() -> Option { + MAP.with(|p| p.borrow().last_key_value()).map(|((ts, _), _)| ts) } -pub fn get_metrics_range(from_ts: TimestampNanos, to_ts: Option) -> Vec<(TimestampNanos, Vec)> { - return MAP.with(|p| { - let borrowed = p.borrow(); - let metrics_in_range = match to_ts { - Some(to_ts) => borrowed.range(from_ts..=to_ts), - None => borrowed.range(from_ts..), - }; - metrics_in_range.into_iter().map(|(ts, storable)| (ts, storable.0)).collect_vec() - }); +pub fn get(node_metrics_key: &NodeMetricsStoredKey) -> Option { + MAP.with(|p| p.borrow().get(node_metrics_key)) } -pub fn metrics_before_ts(node_ids: Vec, ts: &TimestampNanos) -> BTreeMap { - let mut last_metrics: BTreeMap = BTreeMap::new(); - - for node_id in node_ids { - last_metrics.insert(node_id, NodeMetrics{ - node_id, - num_block_failures_total: 0, - num_blocks_proposed_total: 0 - }); - } - - MAP.with(|p| { - let borrowed = p.borrow(); - - for (_, metrics_storable) in borrowed.range(..ts) { - for subnet_metrics in metrics_storable.0 { - for node_metrics in subnet_metrics.node_metrics { - last_metrics.insert(node_metrics.node_id, node_metrics); - } - } - } - }); +pub fn get_metrics_range(from_ts: TimestampNanos, to_ts: Option) -> Vec<(NodeMetricsStoredKey, NodeMetricsStored)> { + let range = { + let first = (from_ts, Principal::anonymous()); + let last = (to_ts.unwrap_or(u64::MAX), Principal::anonymous()); + first..=last + }; + + MAP.with(|p| p.borrow() + .range(range) + .collect_vec()) +} - last_metrics +pub(crate) fn latest_metrics(principal: Principal) -> Option { + let range: std::ops::RangeInclusive<(u64, Principal)> = { + let first = (u64::MIN, principal); + let last = (u64::MAX, principal); + first..=last + }; + + MAP.with(|p| p.borrow() + .range(range) + .take_while(|((_, p), _)| p == &principal) + .max_by_key(|((k, _), _)| *k)) + .map(|(_, v)| v) } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs index a54b548d2..f0e7df916 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/types.rs @@ -3,24 +3,33 @@ use dfn_core::api::PrincipalId; use ic_management_canister_types::NodeMetricsHistoryResponse; use serde::Serialize; -pub type TimestampNanos = u64; pub type PrincipalNodeMetricsHistory = (PrincipalId, Vec); +// Stored in stable structure +pub type TimestampNanos = u64; +pub type NodeMetricsStoredKey = (TimestampNanos, Principal); #[derive(Debug, Deserialize, Serialize, CandidType, Clone)] -pub struct NodeMetrics { - pub node_id: Principal, +pub struct NodeMetricsStored { + pub subnet_assigned: Principal, pub num_blocks_proposed_total: u64, - pub num_block_failures_total: u64, + pub num_blocks_failures_total: u64, + pub num_blocks_proposed: u64, + pub num_blocks_failed: u64, } -#[derive(Deserialize, Serialize, CandidType)] -pub struct SubnetNodeMetrics { - pub subnet_id: Principal, - pub node_metrics: Vec, +// subnet_node_metrics query call +#[derive(Deserialize, CandidType)] +pub struct SubnetNodeMetricsArgs { + pub ts: Option, + pub subnet_id: Option, } -#[derive(Deserialize, Serialize)] -pub struct SubnetNodeMetricsStorable(pub Vec); +#[derive(Debug, Deserialize, Serialize, CandidType, Clone)] +pub struct NodeMetrics { + pub node_id: Principal, + pub num_blocks_proposed_total: u64, + pub num_blocks_failures_total: u64, +} #[derive(Debug, Deserialize, CandidType)] pub struct SubnetNodeMetricsResponse { @@ -29,16 +38,19 @@ pub struct SubnetNodeMetricsResponse { pub node_metrics: Vec, } +// node_rewards query call #[derive(Deserialize, CandidType)] -pub struct SubnetNodeMetricsArgs { - pub ts: Option, - pub subnet_id: Option, +pub struct NodeRewardsArgs { + pub from_ts: u64, + pub to_ts: u64, } -#[derive(Debug, Deserialize, Serialize, CandidType)] -pub struct DailyMetrics { +#[derive(Debug, Clone, Deserialize, Serialize, CandidType)] +pub struct DailyNodeMetrics { pub ts: u64, pub subnet_assigned: Principal, + pub num_blocks_proposed: u64, + pub num_blocks_failed: u64, pub failure_rate: f64, pub rewards_reduction: f64, } @@ -48,11 +60,5 @@ pub struct NodeRewardsResponse { pub node_id: Principal, pub rewards_no_penalty: f64, pub rewards_with_penalty: f64, - pub daily_metrics: Vec, -} - -#[derive(Deserialize, CandidType)] -pub struct NodeRewardsArgs { - pub from_ts: u64, - pub to_ts: u64, + pub daily_node_metrics: Vec, } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index e4ddbf205..22c06ae39 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -2,7 +2,7 @@ type NodeMetrics = record { node_id: principal; num_blocks_proposed_total: nat64; - num_block_failures_total: nat64; + num_blocks_failures_total: nat64; }; type SubnetNodeMetricsResponse = record { @@ -21,9 +21,11 @@ type SubnetNodeMetricsArgs = record { ts: opt nat64; }; -type DailyMetrics = record { +type DailyNodeMetrics = record { ts: nat64; subnet_assigned: principal; + num_blocks_proposed: nat64; + num_blocks_failed: nat64; failure_rate: float64; rewards_reduction: float64; }; @@ -32,7 +34,7 @@ type NodeRewardsResponse = record { node_id: principal; rewards_no_penalty: float64; rewards_with_penalty: float64; - daily_metrics: vec DailyMetrics; + daily_node_metrics: vec DailyNodeMetrics; }; type NodeRewardsArgs = record { From 920f55e19990c3bd7f786580d4d6a16b7fc87688 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 13 Aug 2024 15:46:48 +0200 Subject: [PATCH 26/40] Improvement VM and Bounded type --- .../trustworthy-node-metrics/args-rewards.bin | 4 ++ .../trustworthy-node-metrics/args.bin | 4 +- .../src/metrics_manager.rs | 16 +++-- .../src/stable_memory.rs | 59 +++++++++++-------- 4 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin diff --git a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin new file mode 100644 index 000000000..16769a168 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin @@ -0,0 +1,4 @@ +(record { + from_ts = 0; + to_ts = 1723507199978493357; +}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/args.bin index 32da99f14..45cfd1c81 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/args.bin +++ b/rs/dre-canisters/trustworthy-node-metrics/args.bin @@ -1,4 +1,4 @@ (record { - subnet_id = opt principal "34mm6-e24vu-pnyce-lp4fx-xtz2h-y5jpo-kwzgz-grf4m-v5kvr-xmeu4-tqe"; - ts = opt 1720742398550724680; + subnet_id = opt principal "yinp6-35cfo-wgcd2-oc4ty-2kqpf-t4dul-rfk33-fsq3r-mfmua-m2ngh-jqe"; + ts = opt 0; }) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs index 79b6e2fe3..1496e1442 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs @@ -5,6 +5,7 @@ use dfn_core::api::PrincipalId; use futures::FutureExt; use ic_management_canister_types::{NodeMetricsHistoryArgs, NodeMetricsHistoryResponse}; use ic_protobuf::registry::subnet::v1::SubnetListRecord; +use itertools::Itertools; use crate::types::{NodeMetricsGrouped, NodeMetricsStored, NodeMetricsStoredKey}; use crate::{ @@ -142,6 +143,7 @@ fn store_metrics(node_metrics_storable: Vec<((u64, candid::Principal), NodeMetri } } +/// Update metrics pub async fn update_metrics() -> anyhow::Result<()> { let subnets = fetch_subnets().await?; let latest_ts = stable_memory::latest_ts().unwrap_or_default(); @@ -155,15 +157,17 @@ pub async fn update_metrics() -> anyhow::Result<()> { ); let subnet_metrics: Vec<(PrincipalId, Vec)> = fetch_metrics(subnets, refresh_ts).await?; let grouped_by_node: BTreeMap> = grouped_by_node(subnet_metrics); + let nodes_principal = grouped_by_node.keys().map(|p| p.0).collect_vec(); - for (node_id, node_metrics_grouped) in grouped_by_node { - let first_ts = node_metrics_grouped.first().expect("node_metrics empty").0; - let metrics_before = stable_memory::metrics_before_ts(node_id.0, first_ts); - - let initial_proposed_total = metrics_before.as_ref().map(|(_, metrics)| metrics.num_blocks_proposed_total).unwrap_or(0); - let initial_failed_total = metrics_before.as_ref().map(|(_, metrics)| metrics.num_blocks_failures_total).unwrap_or(0); + let latest_metrics = stable_memory::latest_metrics(nodes_principal); + for (node_id, node_metrics_grouped) in grouped_by_node { + let (initial_proposed_total, initial_failed_total) = latest_metrics + .get(&node_id.0) + .map(|metrics| (metrics.num_blocks_proposed_total, metrics.num_blocks_failures_total)) + .unwrap_or((0, 0)); let node_metrics_storable = node_metrics_storable(node_id, node_metrics_grouped, initial_proposed_total, initial_failed_total); + store_metrics(node_metrics_storable); } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 3746325ed..377b47b51 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -1,12 +1,18 @@ use candid::{Decode, Encode, Principal}; +use ic_stable_structures::memory_manager::{MemoryId, MemoryManager, VirtualMemory}; use ic_stable_structures::{storable::Bound, Storable}; use ic_stable_structures::{DefaultMemoryImpl, StableBTreeMap}; use itertools::Itertools; use std::borrow::Cow; use std::cell::RefCell; +use std::collections::BTreeMap; use crate::types::{NodeMetricsStored, NodeMetricsStoredKey, TimestampNanos}; +type Memory = VirtualMemory; + +const MAX_VALUE_SIZE_BYTE: u32 = 102; + impl Storable for NodeMetricsStored { fn to_bytes(&self) -> std::borrow::Cow<[u8]> { Cow::Owned(Encode!(self).unwrap()) @@ -16,42 +22,49 @@ impl Storable for NodeMetricsStored { Decode!(bytes.as_ref(), Self).unwrap() } - const BOUND: Bound = Bound::Unbounded; + const BOUND: Bound = Bound::Bounded { + max_size: MAX_VALUE_SIZE_BYTE, + is_fixed_size: false, + }; } thread_local! { - pub static MAP: RefCell> = - RefCell::new(StableBTreeMap::init(DefaultMemoryImpl::default())); + + static MEMORY_MANAGER: RefCell> = + RefCell::new(MemoryManager::init(DefaultMemoryImpl::default())); + + static NODE_METRICS_MAP: RefCell> = + RefCell::new(StableBTreeMap::init( + MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(0))) + )); + } pub fn insert(key: NodeMetricsStoredKey, value: NodeMetricsStored) { - MAP.with(|p| p.borrow_mut().insert(key, value)); + NODE_METRICS_MAP.with(|p| p.borrow_mut().insert(key, value)); } pub fn latest_ts() -> Option { - MAP.with(|p| p.borrow().last_key_value()).map(|((ts, _), _)| ts) -} - -#[allow(dead_code)] -pub fn get(node_metrics_key: &NodeMetricsStoredKey) -> Option { - MAP.with(|p| p.borrow().get(node_metrics_key)) + NODE_METRICS_MAP.with(|p| p.borrow().last_key_value()).map(|((ts, _), _)| ts) } pub fn get_metrics_range(from_ts: TimestampNanos, to_ts: Option) -> Vec<(NodeMetricsStoredKey, NodeMetricsStored)> { - let range = { - let first = (from_ts, Principal::anonymous()); - let last = (to_ts.unwrap_or(u64::MAX), Principal::anonymous()); - first..=last - }; + NODE_METRICS_MAP.with(|p| { + let to_ts = to_ts.unwrap_or(u64::MAX); - MAP.with(|p| p.borrow().range(range).collect_vec()) + p.borrow().iter().filter(|((ts, _), _)| *ts >= from_ts && *ts <= to_ts).collect_vec() + }) } -pub fn metrics_before_ts(principal: Principal, ts: u64) -> Option<(NodeMetricsStoredKey, NodeMetricsStored)> { - MAP.with(|p| { - p.borrow() - .range((u64::MIN, principal)..(ts, principal)) - .filter(|((_, p), _)| p == &principal) - .last() - }) +pub fn latest_metrics(principals: Vec) -> BTreeMap { + let mut latest_metrics = BTreeMap::new(); + NODE_METRICS_MAP.with(|p| { + for ((_, principal), value) in p.borrow().iter() { + if principals.contains(&principal) { + latest_metrics.insert(principal, value); + } + } + }); + + latest_metrics } From 12e297dac7f85b0ab56226bf2278739e2fcebcfc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 13 Aug 2024 14:50:38 +0000 Subject: [PATCH 27/40] Github Action: Bazel Repin --- Cargo.Bazel.lock | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index cd478174d..71f237105 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -44322,10 +44322,6 @@ "id": "candid 0.10.10", "target": "candid" }, - { - "id": "chrono 0.4.38", - "target": "chrono" - }, { "id": "ciborium 0.2.2", "target": "ciborium" From a54afef4fd7fcc0cb7411e8ce3464e5a3c5c623b Mon Sep 17 00:00:00 2001 From: Pietro Date: Fri, 16 Aug 2024 18:12:24 +0200 Subject: [PATCH 28/40] Modify rewards computation --- .../src/types.rs | 56 +---- .../trustworthy-node-metrics/args-rewards.bin | 4 + .../src/trustworthy-node-metrics/args.bin | 4 + .../src/trustworthy-node-metrics/src/lib.rs | 7 +- .../src/rewards_manager.rs | 229 +++++++++--------- .../src/stable_memory.rs | 1 - .../trustworthy-node-metrics.did | 11 +- 7 files changed, 143 insertions(+), 169 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args-rewards.bin create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs index beb767589..ab95b08e2 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs @@ -77,46 +77,6 @@ pub struct DailyNodeMetrics { /// `num_blocks_failed` to `num_blocks_total` = `num_blocks_failed` + `num_blocks_proposed`. /// This value ranges from 0.0 (no failures) to 1.0 (all blocks failed). pub failure_rate: f64, - - /// The reduction in rewards for the node, determined by the failure rate. - /// This value is between 0.0 and 1.0, where 0.0 indicates no reduction - /// (full rewards) and 1.0 indicates a complete reduction (no rewards). - pub rewards_reduction: f64, -} - -const MIN_FAILURE_RATE: f64 = 0.1; -const MAX_FAILURE_RATE: f64 = 0.7; - -/// Calculates the daily rewards reduction based on the failure rate. -/// -/// # Arguments -/// -/// * `failure_rate` - A reference to a `f64` value representing the failure rate for the day. -/// -/// # Returns -/// -/// * A `f64` value representing the rewards reduction for the day, where: -/// - `0.0` indicates no reduction (failure rate below the minimum threshold), -/// - `1.0` indicates maximum reduction (failure rate above the maximum threshold), -/// - A value between `0.0` and `1.0` represents a proportional reduction based on the failure rate. -/// -/// # Explanation -/// -/// 1. The function checks if the provided `failure_rate` is below the `MIN_FAILURE_RATE` -> no reduction in rewards. -/// -/// 2. It then checks if the `failure_rate` is above the `MAX_FAILURE_RATE` -> maximum reduction in rewards. -/// -/// 3. If the `failure_rate` is within the defined range (`MIN_FAILURE_RATE` to `MAX_FAILURE_RATE`), -/// the function calculates the reduction proportionally: -/// - The reduction is calculated by normalizing the `failure_rate` within the range, resulting in a value between `0.0` and `1.0`. -fn daily_rewards_reduction(failure_rate: &f64) -> f64 { - if failure_rate < &MIN_FAILURE_RATE { - 0.0 - } else if failure_rate > &MAX_FAILURE_RATE { - 1.0 - } else { - (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) - } } impl DailyNodeMetrics { @@ -128,23 +88,29 @@ impl DailyNodeMetrics { failed_blocks as f64 / total_blocks as f64 }; - let rewards_reduction = daily_rewards_reduction(&failure_rate); - DailyNodeMetrics { ts, subnet_assigned: subnet_assignment, num_blocks_proposed: proposed_blocks, num_blocks_failed: failed_blocks, failure_rate, - rewards_reduction, } } } +#[derive(Debug, Deserialize, CandidType)] +pub struct RewardsStats { + pub blocks_failed: u64, + pub blocks_proposed: u64, + pub blocks_total: u64, + pub failure_rate: f64, + pub rewards_reduction: f64, +} + #[derive(Debug, Deserialize, CandidType)] pub struct NodeRewardsResponse { pub node_id: Principal, - pub rewards_no_penalty: f64, - pub rewards_with_penalty: f64, + pub rewards_percent: f64, pub daily_node_metrics: Vec, + pub rewards_stats: RewardsStats, } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args-rewards.bin b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args-rewards.bin new file mode 100644 index 000000000..16769a168 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args-rewards.bin @@ -0,0 +1,4 @@ +(record { + from_ts = 0; + to_ts = 1723507199978493357; +}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin new file mode 100644 index 000000000..455b7aa91 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin @@ -0,0 +1,4 @@ +(record { + subnet_id = opt principal "yinp6-35cfo-wgcd2-oc4ty-2kqpf-t4dul-rfk33-fsq3r-mfmua-m2ngh-jqe"; + ts = opt 1723507199978493357; +}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index f8437ea9a..699a4daf6 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -111,14 +111,13 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { daily_metrics .into_iter() .map(|(node_id, daily_node_metrics)| { - let rewards_no_penalty = rewards_manager::rewards_no_penalty(&daily_node_metrics); - let rewards_with_penalty = rewards_manager::rewards_with_penalty(&daily_node_metrics); + let (rewards_percent, rewards_stats) = rewards_manager::compute_rewards_percent(&daily_node_metrics); NodeRewardsResponse { node_id, - rewards_no_penalty, - rewards_with_penalty, + rewards_percent, daily_node_metrics, + rewards_stats, } }) .collect_vec() diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs index df8729ca7..47c357690 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/rewards_manager.rs @@ -1,4 +1,39 @@ -use trustworthy_node_metrics_types::types::DailyNodeMetrics; +use trustworthy_node_metrics_types::types::{DailyNodeMetrics, RewardsStats}; + +const MIN_FAILURE_RATE: f64 = 0.1; +const MAX_FAILURE_RATE: f64 = 0.7; + +/// Calculates the rewards reduction based on the failure rate. +/// +/// # Arguments +/// +/// * `failure_rate` - A reference to a `f64` value representing the failure rate. +/// +/// # Returns +/// +/// * A `f64` value representing the rewards reduction, where: +/// - `0.0` indicates no reduction (failure rate below the minimum threshold), +/// - `1.0` indicates maximum reduction (failure rate above the maximum threshold), +/// - A value between `0.0` and `1.0` represents a proportional reduction based on the failure rate. +/// +/// # Explanation +/// +/// 1. The function checks if the provided `failure_rate` is below the `MIN_FAILURE_RATE` -> no reduction in rewards. +/// +/// 2. It then checks if the `failure_rate` is above the `MAX_FAILURE_RATE` -> maximum reduction in rewards. +/// +/// 3. If the `failure_rate` is within the defined range (`MIN_FAILURE_RATE` to `MAX_FAILURE_RATE`), +/// the function calculates the reduction proportionally: +/// - The reduction is calculated by normalizing the `failure_rate` within the range, resulting in a value between `0.0` and `1.0`. +fn rewards_reduction(failure_rate: &f64) -> f64 { + if failure_rate < &MIN_FAILURE_RATE { + 0.0 + } else if failure_rate > &MAX_FAILURE_RATE { + 1.0 + } else { + (failure_rate - MIN_FAILURE_RATE) / (MAX_FAILURE_RATE - MIN_FAILURE_RATE) + } +} /// Computes the rewards percentage based on the daily reward reductions WITH consecutive days penalty. /// @@ -21,6 +56,7 @@ use trustworthy_node_metrics_types::types::DailyNodeMetrics; /// /// 3. The overall reduction is calculated by dividing the total reduction (`reduction_sum`) by the number of active days. /// The reduction is then normalized by ensuring it does not exceed 1.0. +#[allow(dead_code)] pub fn rewards_with_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { let active_days = daily_metrics.len(); let mut reduction_sum = 0.0; @@ -31,7 +67,7 @@ pub fn rewards_with_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { // Just if we want to count the day unassigned as 0.0 reduction // we would need to check if previous daily metrics is <= 24hrs // before current metrics - let daily_reduction: f64 = metrics.rewards_reduction; + let daily_reduction: f64 = metrics.num_blocks_failed as f64 / (metrics.num_blocks_failed + metrics.num_blocks_proposed) as f64; if daily_reduction == 0.0 { if consecutive_count > 0 { @@ -56,10 +92,9 @@ pub fn rewards_with_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { ((1.0 - reduction_normalized) * 100.0).round() / 100.0 } -/// Rewards no penalty +/// Compute rewards percent /// -/// Computes the rewards percentage based on the daily reward reductions WITHOUT consecutive days penalty. -/// `overall_reduction` is defined as the average of the daily reward reductions. +/// Computes the rewards percentage based on the overall failure rate in the period. /// /// # Arguments /// @@ -67,20 +102,41 @@ pub fn rewards_with_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { /// /// # Returns /// -/// * A `f64` value representing the rewards percentage after overall reductions, rounded to two decimal places. +/// * A `f64` value representing the rewards percentage left after the rewards reduction, rounded to two decimal places. /// /// # Explanation /// -/// 1. The function iterates through each day's metrics, summing up the `rewards_reduction` values across all days. -/// 2. The `overall_reduction` is calculated by dividing the total `reduction_sum` by the number of active days. -/// 3. Finally, the function calculates the rewards percentage without penalty by subtracting `overall_reduction` from 1.0, -/// multiplying by 100, and rounding to two decimal places before returning the result. -pub fn rewards_no_penalty(daily_metrics: &[DailyNodeMetrics]) -> f64 { - let active_days = daily_metrics.len(); - let reduction_sum: f64 = daily_metrics.iter().map(|metrics| metrics.rewards_reduction).sum(); - let overall_reduction = reduction_sum / (active_days as f64); - - ((1.0 - overall_reduction) * 100.0).round() / 100.0 +/// 1. The function iterates through each day's metrics, summing up the `daily_failed` and `daily_total` blocks across all days. +/// 2. The `overall_failure_rate` is calculated by dividing the `overall_failed` blocks by the `overall_total` blocks. +/// 3. The `rewards_reduction` function is applied to `overall_failure_rate`. +/// 3. Finally, the rewards percentage to be distrubuted to the node is computed. +pub fn compute_rewards_percent(daily_metrics: &[DailyNodeMetrics]) -> (f64, RewardsStats) { + let (overall_failed, overall_proposed): (u64, u64) = daily_metrics + .iter() + .map(|metrics| { + let daily_failed = metrics.num_blocks_failed; + let daily_proposed = metrics.num_blocks_proposed; + + (daily_failed, daily_proposed) + }) + .fold((0, 0), |(failed_acc, total_acc), (failed, total)| { + (failed_acc + failed, total_acc + total) + }); + let overall_total = overall_failed + overall_proposed; + + let overall_failure_rate = overall_failed as f64 / overall_total as f64; + let rewards_reduction = rewards_reduction(&overall_failure_rate); + let rewards_percent = ((1.0 - rewards_reduction) * 100.0).round() / 100.0; + + let rewards_stats = RewardsStats { + blocks_failed: overall_failed, + blocks_proposed: overall_proposed, + blocks_total: overall_total, + failure_rate: overall_failure_rate, + rewards_reduction, + }; + + (rewards_percent, rewards_stats) } #[cfg(test)] @@ -123,97 +179,51 @@ mod tests { } #[test] - fn test_rewards_no_penalty() { - // Failure Rate = 40% Rewards reduction = 50% - // 0.5 * 5 days / 30 days = 0.08 -> Rewards 0.92 - let daily_metrics: Vec = daily_mocked_metrics(vec![MockedMetrics::new(5, 6, 4), MockedMetrics::new(25, 10, 0)]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 0.92); - - // Failure Rate = 40% Rewards reduction = 50% - // 0.5 / 2 days = 0.25 -> Rewards 0.75 - let daily_metrics: Vec = daily_mocked_metrics(vec![ - MockedMetrics::new(1, 6, 4), - MockedMetrics::new(1, 91, 9), // no penalty - ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 0.75); - - // Failure Rate = 40% Rewards reduction = 50% 10 days - // Failure Rate = 30% Rewards reduction = 33% - // (0.5 * 10 + 0.33) / 11 = 0.48 Rewards 0.67 - let daily_metrics: Vec = daily_mocked_metrics(vec![ - MockedMetrics::new(1, 7, 3), // no penalty - ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 0.67); - } - - #[test] - fn test_rewards_with_penalty() { - // Failure Rate = 40% Rewards reduction = 50% - // 0.5 * 5^2 days / 30 days = 0.42 -> Rewards 0.58 - let daily_metrics: Vec = daily_mocked_metrics(vec![MockedMetrics::new(5, 6, 4), MockedMetrics::new(25, 10, 0)]); - let rewards = rewards_with_penalty(&daily_metrics); - assert_eq!(rewards, 0.58); - - // Failure Rate = 40% Rewards reduction = 50% - // 0.5 / 2 days = 0.25 -> Rewards 0.75 + fn test_rewards_percent() { + // Overall failed = 130 Overall total = 500 Failure rate = 0.26 + // rewards_reduction = 0.266 + let daily_metrics: Vec = daily_mocked_metrics(vec![MockedMetrics::new(20, 6, 4), MockedMetrics::new(25, 10, 2)]); + let (rewards_percent, _) = compute_rewards_percent(&daily_metrics); + assert_eq!(rewards_percent, 0.73); + + // Overall failed = 45 Overall total = 450 Failure rate = 0.1 + // rewards_reduction = 0.0 let daily_metrics: Vec = daily_mocked_metrics(vec![ - MockedMetrics::new(1, 6, 4), - MockedMetrics::new(1, 91, 9), // no penalty + MockedMetrics::new(1, 400, 20), + MockedMetrics::new(1, 5, 25), // no penalty ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 0.75); + let (rewards_percent, _) = compute_rewards_percent(&daily_metrics); + assert_eq!(rewards_percent, 1.0); - // Failure Rate = 40% Rewards reduction = 50% 10 days - // Failure Rate = 30% Rewards reduction = 33% - // (0.5 * 10 + 0.33) / 11 -> Reduction 0.48 Rewards 0.67 + // Overall failed = 5 Overall total = 10 Failure rate = 0.5 + // rewards_reduction = 0.666 let daily_metrics: Vec = daily_mocked_metrics(vec![ - MockedMetrics::new(1, 7, 3), // no penalty + MockedMetrics::new(1, 5, 5), // no penalty ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 0.67); + let (rewards_percent, _) = compute_rewards_percent(&daily_metrics); + assert_eq!(rewards_percent, 0.33); } #[test] - fn test_rewards_no_penalty_max_reduction() { + fn test_rewards_percent_max_reduction() { let daily_metrics: Vec = daily_mocked_metrics(vec![ MockedMetrics::new(10, 5, 95), // max failure rate ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 0.0); - } - - #[test] - fn test_rewards_with_penalty_max_reduction() { - let daily_metrics: Vec = daily_mocked_metrics(vec![ - MockedMetrics::new(1, 9, 91), // max failure rate - ]); - let rewards = rewards_with_penalty(&daily_metrics); - assert_eq!(rewards, 0.0); + let (rewards_percent, _) = compute_rewards_percent(&daily_metrics); + assert_eq!(rewards_percent, 0.0); } #[test] - fn test_rewards_no_penalty_min_reduction() { + fn test_rewards_percent_min_reduction() { let daily_metrics: Vec = daily_mocked_metrics(vec![ MockedMetrics::new(10, 9, 1), // min failure rate ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 1.0); + let (rewards_percent, _) = compute_rewards_percent(&daily_metrics); + assert_eq!(rewards_percent, 1.0); } #[test] - fn test_rewards_with_penalty_min_reduction() { - let daily_metrics: Vec = daily_mocked_metrics(vec![ - MockedMetrics::new(10, 9, 1), // min failure rate - ]); - let rewards = rewards_no_penalty(&daily_metrics); - assert_eq!(rewards, 1.0); - } - - #[test] - fn test_same_rewards_if_gaps_no_penalty() { + fn test_same_rewards_percent_if_gaps_no_penalty() { let gap = MockedMetrics::new(1, 10, 0); let daily_metrics_mid_gap: Vec = @@ -225,23 +235,16 @@ mod tests { let daily_metrics_right_gap: Vec = daily_mocked_metrics(vec![gap.clone(), MockedMetrics::new(1, 6, 4), MockedMetrics::new(1, 7, 3)]); - assert_eq!(rewards_no_penalty(&daily_metrics_mid_gap), 0.72); + assert_eq!(compute_rewards_percent(&daily_metrics_mid_gap).0, 0.78); - assert_eq!(rewards_no_penalty(&daily_metrics_mid_gap), rewards_no_penalty(&daily_metrics_left_gap)); - assert_eq!(rewards_no_penalty(&daily_metrics_right_gap), rewards_no_penalty(&daily_metrics_left_gap)); - } - - #[test] - fn test_less_rewards_if_consecutive_with_penalty() { - let gap = MockedMetrics::new(1, 10, 0); - - let daily_metrics_no_gap: Vec = daily_mocked_metrics(vec![MockedMetrics::new(4, 8, 2)]); - - let daily_metrics_with_gap: Vec = daily_mocked_metrics(vec![MockedMetrics::new(2, 8, 2), gap, MockedMetrics::new(2, 8, 2)]); - - assert_eq!(rewards_with_penalty(&daily_metrics_no_gap), 0.33); - - assert!(rewards_with_penalty(&daily_metrics_with_gap) > rewards_with_penalty(&daily_metrics_no_gap)); + assert_eq!( + compute_rewards_percent(&daily_metrics_mid_gap).0, + compute_rewards_percent(&daily_metrics_left_gap).0 + ); + assert_eq!( + compute_rewards_percent(&daily_metrics_right_gap).0, + compute_rewards_percent(&daily_metrics_left_gap).0 + ); } #[test] @@ -252,20 +255,12 @@ mod tests { MockedMetrics::new(25, 10, 0), ]); - let mut daily_metrics_1 = daily_metrics.clone(); - let rewards = rewards_with_penalty(&daily_metrics_1); - daily_metrics_1.reverse(); - let rewards_rev = rewards_with_penalty(&daily_metrics_1); - - assert_eq!(rewards, 0.39); - assert_eq!(rewards_rev, rewards); - - let mut daily_metrics_2 = daily_metrics.clone(); - let rewards = rewards_no_penalty(&daily_metrics_2); - daily_metrics_2.reverse(); - let rewards_rev = rewards_no_penalty(&daily_metrics_2); + let mut daily_metrics = daily_metrics.clone(); + let (rewards_percent, _) = compute_rewards_percent(&daily_metrics); + daily_metrics.reverse(); + let (rewards_percent_rev, _) = compute_rewards_percent(&daily_metrics); - assert_eq!(rewards, 0.9); - assert_eq!(rewards_rev, rewards); + assert_eq!(rewards_percent, 1.0); + assert_eq!(rewards_percent_rev, rewards_percent); } } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 98de71c69..aee605f85 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -10,7 +10,6 @@ use trustworthy_node_metrics_types::types::{NodeMetricsStored, NodeMetricsStored type Memory = VirtualMemory; thread_local! { - static MEMORY_MANAGER: RefCell> = RefCell::new(MemoryManager::init(DefaultMemoryImpl::default())); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index 22c06ae39..86704eda5 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -27,14 +27,21 @@ type DailyNodeMetrics = record { num_blocks_proposed: nat64; num_blocks_failed: nat64; failure_rate: float64; +}; + +type RewardsStats = record { + blocks_failed: nat64; + blocks_proposed: nat64; + blocks_total: nat64; + failure_rate: float64; rewards_reduction: float64; }; type NodeRewardsResponse = record { node_id: principal; - rewards_no_penalty: float64; - rewards_with_penalty: float64; + rewards_percent: float64; daily_node_metrics: vec DailyNodeMetrics; + rewards_stats: RewardsStats; }; type NodeRewardsArgs = record { From 55302268a7f0c1c9ee218493726ea273c400c16c Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 20 Aug 2024 18:22:39 +0200 Subject: [PATCH 29/40] Add node providers mapping --- Cargo.lock | 2 + .../trustworthy-node-metrics/args.bin | 2 +- .../trustworthy-node-metrics/pool_logs.sh | 2 +- .../src/types.rs | 1 + .../src/trustworthy-node-metrics/Cargo.toml | 2 + .../src/trustworthy-node-metrics/args.bin | 4 +- .../src/trustworthy-node-metrics/src/lib.rs | 6 +- .../src/metrics_manager.rs | 87 +++++++++++++++---- .../src/stable_memory.rs | 19 +++- .../trustworthy-node-metrics.did | 1 + 10 files changed, 100 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39f80ab88..0737fb285 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9038,12 +9038,14 @@ dependencies = [ "candid", "dfn_core", "futures", + "ic-base-types", "ic-cdk 0.15.0", "ic-cdk-macros 0.15.0", "ic-cdk-timers 0.9.0", "ic-management-canister-types", "ic-nns-common", "ic-protobuf", + "ic-registry-keys", "ic-stable-structures", "itertools 0.13.0", "trustworthy-node-metrics-types", diff --git a/rs/dre-canisters/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/args.bin index 45cfd1c81..96a0634b7 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/args.bin +++ b/rs/dre-canisters/trustworthy-node-metrics/args.bin @@ -1,4 +1,4 @@ (record { - subnet_id = opt principal "yinp6-35cfo-wgcd2-oc4ty-2kqpf-t4dul-rfk33-fsq3r-mfmua-m2ngh-jqe"; + subnet_id = opt principal "tfiqy-cbhk2-fkeq5-5p5r5-kk7eg-kctmo-tfaor-jogn2-ouxpw-un4kh-kqe"; ts = opt 0; }) diff --git a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh index cd448a976..904bbbeeb 100755 --- a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh +++ b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh @@ -3,7 +3,7 @@ # Function to fetch logs and filter out new lines fetch_and_filter_logs() { # Fetch logs - new_logs=$(dfx canister logs trustworthy-node-metrics --network staging) + new_logs=$(dfx canister logs trustworthy-node-metrics --network ic) # Compare with previous logs to find new ones while IFS= read -r line; do diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs index ab95b08e2..c5a545a64 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-types/src/types.rs @@ -110,6 +110,7 @@ pub struct RewardsStats { #[derive(Debug, Deserialize, CandidType)] pub struct NodeRewardsResponse { pub node_id: Principal, + pub node_provider_id: Principal, pub rewards_percent: f64, pub daily_node_metrics: Vec, pub rewards_stats: RewardsStats, diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml index 612aae911..5514589e3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/Cargo.toml @@ -25,3 +25,5 @@ ic-protobuf = { workspace = true } ic-nns-common = { workspace = true } dfn_core = { workspace = true } trustworthy-node-metrics-types = { workspace = true } +ic-base-types = { workspace = true } +ic-registry-keys = { workspace = true } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin index 455b7aa91..a2848d16f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/args.bin @@ -1,4 +1,4 @@ (record { - subnet_id = opt principal "yinp6-35cfo-wgcd2-oc4ty-2kqpf-t4dul-rfk33-fsq3r-mfmua-m2ngh-jqe"; - ts = opt 1723507199978493357; + subnet_id = opt principal "eq6en-6jqla-fbu5s-daskr-h6hx2-376n5-iqabl-qgrng-gfqmv-n3yjr-mqe"; + ts = opt 0; }) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 699a4daf6..16b5dafaf 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -1,9 +1,9 @@ use candid::Principal; use ic_cdk_macros::*; use itertools::Itertools; -use std::collections::{self, btree_map::Entry, BTreeMap}; +use std::collections::{btree_map::Entry, BTreeMap}; use trustworthy_node_metrics_types::types::{ - DailyNodeMetrics, NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, + NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, SubnetNodeMetricsArgs, SubnetNodeMetricsResponse, }; mod metrics_manager; @@ -112,9 +112,11 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { .into_iter() .map(|(node_id, daily_node_metrics)| { let (rewards_percent, rewards_stats) = rewards_manager::compute_rewards_percent(&daily_node_metrics); + let node_provider_id: stable_memory::get_node_provider(&node_id).unwrap_or(Principal::anonymous()) NodeRewardsResponse { node_id, + node_provider_id, rewards_percent, daily_node_metrics, rewards_stats, diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs index d3bce3c94..40d4dc713 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs @@ -1,10 +1,14 @@ use std::collections::BTreeMap; -use anyhow::Ok; +use anyhow::{anyhow, Ok}; use dfn_core::api::PrincipalId; use futures::FutureExt; +use ic_base_types::NodeId; use ic_management_canister_types::{NodeMetricsHistoryArgs, NodeMetricsHistoryResponse}; +use ic_protobuf::registry::node::v1::NodeRecord; +use ic_protobuf::registry::node_operator::v1::NodeOperatorRecord; use ic_protobuf::registry::subnet::v1::SubnetListRecord; +use ic_registry_keys::{make_node_operator_record_key, make_node_record_key}; use crate::stable_memory; use itertools::Itertools; @@ -109,6 +113,40 @@ async fn fetch_subnets() -> anyhow::Result> { Ok(subnets) } +/// Fetch node provider +/// +/// Fetch node provider from the registry canister given node_id +async fn fetch_node_provider(node_id: &PrincipalId) -> anyhow::Result { + let node_id = NodeId::from(*node_id); + + let node_record_key = make_node_record_key(node_id); + let (node_record, _) = ic_nns_common::registry::get_value::(node_record_key.as_bytes(), None) + .await + .map_err(|e| { + anyhow!( + "Error getting the node_record from the registry for node {}. Error: {:?}", + node_principal, + e + ) + })?; + + let node_operator_id: PrincipalId = node_record.node_operator_id.try_into()?; + let node_operator_key = make_node_operator_record_key(node_operator_id); + let (node_operator_record, _) = ic_nns_common::registry::get_value::(node_operator_key.as_bytes(), None) + .await + .map_err(|e| { + anyhow!( + "Error getting the node_operator_record from the registry for node {}. Error: {:?}", + node_principal, + e + ) + })?; + + let node_provider_id: PrincipalId = node_operator_record.node_provider_principal_id.try_into()?; + + Ok(node_provider_id) +} + // Calculates the daily proposed and failed blocks fn calculate_daily_metrics(last_proposed_total: u64, last_failed_total: u64, current_proposed_total: u64, current_failed_total: u64) -> (u64, u64) { if last_failed_total > current_failed_total || last_proposed_total > current_proposed_total { @@ -135,9 +173,33 @@ fn grouped_by_node(subnet_metrics: Vec<(PrincipalId, Vec) { - for (key, node_metrics) in node_metrics_storable { - stable_memory::insert(key, node_metrics) +async fn update_node_providers(nodes_principal: Vec<&PrincipalId>) -> anyhow::Result<()> { + for node_principal in nodes_principal { + let maybe_node_provider = stable_memory::get_node_provider(&node_principal.0); + + if maybe_node_provider.is_none() { + let node_provider_id = fetch_node_provider(node_principal).await?; + + stable_memory::insert_node_provider(node_principal.0, node_provider_id.0) + } + } + Ok(()) +} + +fn update_node_metrics(metrics_by_node: BTreeMap>) { + let principals = metrics_by_node.keys().map(|p| p.0).collect_vec(); + let latest_metrics = stable_memory::latest_metrics(&principals); + + for (node_id, node_metrics_grouped) in metrics_by_node { + let (initial_proposed_total, initial_failed_total) = latest_metrics + .get(&node_id.0) + .map(|metrics| (metrics.num_blocks_proposed_total, metrics.num_blocks_failures_total)) + .unwrap_or((0, 0)); + let node_metrics_storable = node_metrics_storable(node_id, node_metrics_grouped, initial_proposed_total, initial_failed_total); + + for (key, node_metrics) in node_metrics_storable { + stable_memory::insert_node_metrics(key, node_metrics) + } } } @@ -154,20 +216,11 @@ pub async fn update_metrics() -> anyhow::Result<()> { refresh_ts ); let subnet_metrics: Vec<(PrincipalId, Vec)> = fetch_metrics(subnets, refresh_ts).await?; - let grouped_by_node: BTreeMap> = grouped_by_node(subnet_metrics); - let nodes_principal = grouped_by_node.keys().map(|p| p.0).collect_vec(); - - let latest_metrics = stable_memory::latest_metrics(nodes_principal); + let metrics_by_node: BTreeMap> = grouped_by_node(subnet_metrics); + let nodes_principal: Vec<&PrincipalId> = metrics_by_node.keys().collect_vec(); - for (node_id, node_metrics_grouped) in grouped_by_node { - let (initial_proposed_total, initial_failed_total) = latest_metrics - .get(&node_id.0) - .map(|metrics| (metrics.num_blocks_proposed_total, metrics.num_blocks_failures_total)) - .unwrap_or((0, 0)); - let node_metrics_storable = node_metrics_storable(node_id, node_metrics_grouped, initial_proposed_total, initial_failed_total); - - store_metrics(node_metrics_storable); - } + update_node_providers(nodes_principal).await?; + update_node_metrics(metrics_by_node); Ok(()) } diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index aee605f85..47d6d3c75 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -18,9 +18,14 @@ thread_local! { MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(0))) )); + static NODE_PROVIDER_MAP: RefCell> = + RefCell::new(StableBTreeMap::init( + MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(1))) + )); + } -pub fn insert(key: NodeMetricsStoredKey, value: NodeMetricsStored) { +pub fn insert_node_metrics(key: NodeMetricsStoredKey, value: NodeMetricsStored) { NODE_METRICS_MAP.with(|p| p.borrow_mut().insert(key, value)); } @@ -36,11 +41,11 @@ pub fn get_metrics_range(from_ts: TimestampNanos, to_ts: Option) }) } -pub fn latest_metrics(principals: Vec) -> BTreeMap { +pub fn latest_metrics(nodes_principal: &[Principal]) -> BTreeMap { let mut latest_metrics = BTreeMap::new(); NODE_METRICS_MAP.with(|p| { for ((_, principal), value) in p.borrow().iter() { - if principals.contains(&principal) { + if nodes_principal.contains(&principal) { latest_metrics.insert(principal, value); } } @@ -48,3 +53,11 @@ pub fn latest_metrics(principals: Vec) -> BTreeMap Option { + NODE_PROVIDER_MAP.with_borrow(|np_map| np_map.get(node_principal)) +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did index 86704eda5..286fb5fb0 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/trustworthy-node-metrics.did @@ -39,6 +39,7 @@ type RewardsStats = record { type NodeRewardsResponse = record { node_id: principal; + node_provider_id: principal; rewards_percent: float64; daily_node_metrics: vec DailyNodeMetrics; rewards_stats: RewardsStats; From ca178e68e41fd867f05977f30246acc88a9502e7 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 20 Aug 2024 19:30:20 +0200 Subject: [PATCH 30/40] Fixed types --- rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin | 4 ---- rs/dre-canisters/trustworthy-node-metrics/args.bin | 4 ---- .../{ => src/trustworthy-node-metrics}/pool_logs.sh | 0 .../src/trustworthy-node-metrics/src/lib.rs | 7 +++---- .../src/trustworthy-node-metrics/src/metrics_manager.rs | 4 ++-- 5 files changed, 5 insertions(+), 14 deletions(-) delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/args.bin rename rs/dre-canisters/trustworthy-node-metrics/{ => src/trustworthy-node-metrics}/pool_logs.sh (100%) diff --git a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin deleted file mode 100644 index 16769a168..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin +++ /dev/null @@ -1,4 +0,0 @@ -(record { - from_ts = 0; - to_ts = 1723507199978493357; -}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/args.bin deleted file mode 100644 index 96a0634b7..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/args.bin +++ /dev/null @@ -1,4 +0,0 @@ -(record { - subnet_id = opt principal "tfiqy-cbhk2-fkeq5-5p5r5-kk7eg-kctmo-tfaor-jogn2-ouxpw-un4kh-kqe"; - ts = opt 0; -}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/pool_logs.sh similarity index 100% rename from rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh rename to rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/pool_logs.sh diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index 16b5dafaf..f4a896418 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -1,10 +1,9 @@ use candid::Principal; use ic_cdk_macros::*; use itertools::Itertools; -use std::collections::{btree_map::Entry, BTreeMap}; +use std::collections::{self, btree_map::Entry, BTreeMap}; use trustworthy_node_metrics_types::types::{ - NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, SubnetNodeMetricsArgs, - SubnetNodeMetricsResponse, + DailyNodeMetrics, NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, SubnetNodeMetricsResponse }; mod metrics_manager; mod rewards_manager; @@ -112,7 +111,7 @@ fn node_rewards(args: NodeRewardsArgs) -> Vec { .into_iter() .map(|(node_id, daily_node_metrics)| { let (rewards_percent, rewards_stats) = rewards_manager::compute_rewards_percent(&daily_node_metrics); - let node_provider_id: stable_memory::get_node_provider(&node_id).unwrap_or(Principal::anonymous()) + let node_provider_id = stable_memory::get_node_provider(&node_id).unwrap_or(Principal::anonymous()); NodeRewardsResponse { node_id, diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs index 40d4dc713..43e3dae46 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs @@ -125,7 +125,7 @@ async fn fetch_node_provider(node_id: &PrincipalId) -> anyhow::Result anyhow::Result Date: Tue, 20 Aug 2024 19:40:28 +0200 Subject: [PATCH 31/40] Cargo lock --- Cargo.lock | 387 ++++++++++++++++++++++++++--------------------------- 1 file changed, 193 insertions(+), 194 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0737fb285..aab53a540 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -177,7 +177,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -372,7 +372,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", "synstructure", ] @@ -384,7 +384,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -432,7 +432,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -454,7 +454,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -465,7 +465,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -801,7 +801,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", "syn_derive", ] @@ -1033,7 +1033,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1076,9 +1076,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68064e60dbf1f17005c2fde4d07c16d8baa506fd7ffed8ccab702d93617975c7" +checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" dependencies = [ "jobserver", "libc", @@ -1200,9 +1200,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.16" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c677cd0126f3026d8b093fa29eae5d812fde5c05bc66dbb29d0374eea95113a" +checksum = "1ee158892bd7ce77aa15c208abbdb73e155d191c287a659b57abd5adb92feb03" dependencies = [ "clap 4.5.16", ] @@ -1229,7 +1229,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1608,7 +1608,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1642,7 +1642,7 @@ dependencies = [ [[package]] name = "cycles-minting-canister" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "base64 0.13.1", @@ -1725,7 +1725,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1747,7 +1747,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1862,7 +1862,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1883,7 +1883,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1893,7 +1893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -1906,13 +1906,13 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] name = "dfn_candid" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "dfn_core", @@ -1924,7 +1924,7 @@ dependencies = [ [[package]] name = "dfn_core" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "on_wire", @@ -1933,7 +1933,7 @@ dependencies = [ [[package]] name = "dfn_http" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "dfn_candid", @@ -1945,7 +1945,7 @@ dependencies = [ [[package]] name = "dfn_http_metrics" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "dfn_candid", "dfn_core", @@ -1957,7 +1957,7 @@ dependencies = [ [[package]] name = "dfn_protobuf" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "on_wire", "prost", @@ -2068,7 +2068,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -2281,7 +2281,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -2400,7 +2400,7 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fe-derive" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "num-bigint-dig", @@ -2571,7 +2571,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -3155,7 +3155,7 @@ dependencies = [ [[package]] name = "ic-adapter-metrics-client" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-adapter-metrics-service", "ic-async-utils", @@ -3170,7 +3170,7 @@ dependencies = [ [[package]] name = "ic-adapter-metrics-service" version = "0.1.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "prost", "prost-build", @@ -3222,7 +3222,7 @@ dependencies = [ [[package]] name = "ic-async-utils" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "anyhow", "async-stream", @@ -3242,7 +3242,7 @@ dependencies = [ [[package]] name = "ic-base-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "byte-unit", "bytes", @@ -3269,7 +3269,7 @@ dependencies = [ [[package]] name = "ic-btc-replica-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-btc-interface", @@ -3282,7 +3282,7 @@ dependencies = [ [[package]] name = "ic-canister-client" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "backoff", "futures-util", @@ -3309,7 +3309,7 @@ dependencies = [ [[package]] name = "ic-canister-client-sender" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-crypto-ecdsa-secp256k1", @@ -3322,7 +3322,7 @@ dependencies = [ [[package]] name = "ic-canister-log" version = "0.2.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "serde", ] @@ -3330,7 +3330,7 @@ dependencies = [ [[package]] name = "ic-canister-profiler" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-metrics-encoder", "ic0 0.18.11", @@ -3373,7 +3373,7 @@ dependencies = [ [[package]] name = "ic-canisters-http-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "serde", @@ -3383,7 +3383,7 @@ dependencies = [ [[package]] name = "ic-canonical-state" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-canonical-state-tree-hash", @@ -3407,7 +3407,7 @@ dependencies = [ [[package]] name = "ic-canonical-state-tree-hash" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-tree-hash", "itertools 0.12.1", @@ -3432,7 +3432,7 @@ dependencies = [ [[package]] name = "ic-cdk" version = "0.15.0" -source = "git+https://github.com/dfinity/cdk-rs.git?rev=deb1e15ae4c60333636f0581e0f30d169d8c9a0a#deb1e15ae4c60333636f0581e0f30d169d8c9a0a" +source = "git+https://github.com/dfinity/cdk-rs.git?rev=bd17d57a7b8ca59665fea5fad6143ca02724d03b#bd17d57a7b8ca59665fea5fad6143ca02724d03b" dependencies = [ "candid", "ic-cdk-macros 0.15.0", @@ -3472,14 +3472,14 @@ dependencies = [ [[package]] name = "ic-cdk-macros" version = "0.15.0" -source = "git+https://github.com/dfinity/cdk-rs.git?rev=deb1e15ae4c60333636f0581e0f30d169d8c9a0a#deb1e15ae4c60333636f0581e0f30d169d8c9a0a" +source = "git+https://github.com/dfinity/cdk-rs.git?rev=bd17d57a7b8ca59665fea5fad6143ca02724d03b#bd17d57a7b8ca59665fea5fad6143ca02724d03b" dependencies = [ "candid", "proc-macro2", "quote", "serde", "serde_tokenstream 0.2.1", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -3499,7 +3499,7 @@ dependencies = [ [[package]] name = "ic-cdk-timers" version = "0.9.0" -source = "git+https://github.com/dfinity/cdk-rs.git?rev=deb1e15ae4c60333636f0581e0f30d169d8c9a0a#deb1e15ae4c60333636f0581e0f30d169d8c9a0a" +source = "git+https://github.com/dfinity/cdk-rs.git?rev=bd17d57a7b8ca59665fea5fad6143ca02724d03b#bd17d57a7b8ca59665fea5fad6143ca02724d03b" dependencies = [ "futures", "ic-cdk 0.15.0", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "ic-certification" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "ic-crypto-tree-hash", @@ -3539,7 +3539,7 @@ dependencies = [ [[package]] name = "ic-certification-version" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "strum 0.26.3", "strum_macros 0.26.4", @@ -3559,7 +3559,7 @@ dependencies = [ [[package]] name = "ic-config" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-protobuf", @@ -3574,12 +3574,12 @@ dependencies = [ [[package]] name = "ic-constants" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-crypto-ecdsa-secp256k1" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hmac", "k256", @@ -3587,6 +3587,7 @@ dependencies = [ "num-bigint 0.4.6", "pem 1.1.1", "rand", + "rand_chacha", "simple_asn1", "zeroize", ] @@ -3594,7 +3595,7 @@ dependencies = [ [[package]] name = "ic-crypto-ed25519" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "curve25519-dalek", "ed25519-dalek", @@ -3608,7 +3609,7 @@ dependencies = [ [[package]] name = "ic-crypto-getrandom-for-wasm" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "getrandom", ] @@ -3616,7 +3617,7 @@ dependencies = [ [[package]] name = "ic-crypto-interfaces-sig-verification" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-types", ] @@ -3624,7 +3625,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-basic-sig-der-utils" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "ic-types", @@ -3634,7 +3635,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-basic-sig-ed25519" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "curve25519-dalek", @@ -3656,7 +3657,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-bls12-381-type" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "ic_bls12_381", @@ -3674,7 +3675,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-hmac" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-internal-sha2", ] @@ -3682,7 +3683,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-multi-sig-bls12381" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "hex", @@ -3701,7 +3702,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-seed" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "ic-crypto-sha2", @@ -3714,7 +3715,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-sha2" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "sha2 0.10.8", ] @@ -3722,7 +3723,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-threshold-sig-bls12381" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "cached 0.49.3", @@ -3748,7 +3749,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-threshold-sig-ecdsa" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "curve25519-dalek", "fe-derive", @@ -3778,7 +3779,7 @@ dependencies = [ [[package]] name = "ic-crypto-internal-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "arrayvec 0.7.4", "hex", @@ -3795,7 +3796,7 @@ dependencies = [ [[package]] name = "ic-crypto-node-key-validation" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "ic-base-types", @@ -3813,7 +3814,7 @@ dependencies = [ [[package]] name = "ic-crypto-secrets-containers" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "serde", "zeroize", @@ -3822,7 +3823,7 @@ dependencies = [ [[package]] name = "ic-crypto-sha2" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-internal-sha2", ] @@ -3830,7 +3831,7 @@ dependencies = [ [[package]] name = "ic-crypto-tls-cert-validation" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "ic-crypto-internal-basic-sig-ed25519", @@ -3843,7 +3844,7 @@ dependencies = [ [[package]] name = "ic-crypto-tree-hash" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-internal-types", "ic-crypto-sha2", @@ -3856,7 +3857,7 @@ dependencies = [ [[package]] name = "ic-crypto-utils-basic-sig" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-crypto-ed25519", @@ -3866,7 +3867,7 @@ dependencies = [ [[package]] name = "ic-crypto-utils-ni-dkg" version = "0.8.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-internal-types", "ic-protobuf", @@ -3876,7 +3877,7 @@ dependencies = [ [[package]] name = "ic-crypto-utils-threshold-sig" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "ic-crypto-internal-threshold-sig-bls12381", @@ -3887,7 +3888,7 @@ dependencies = [ [[package]] name = "ic-crypto-utils-threshold-sig-der" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "ic-crypto-internal-types", @@ -3898,7 +3899,7 @@ dependencies = [ [[package]] name = "ic-error-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-protobuf", "ic-utils 0.9.0", @@ -3910,7 +3911,7 @@ dependencies = [ [[package]] name = "ic-http-endpoints-metrics" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "axum 0.7.5", "ic-async-utils", @@ -3927,7 +3928,7 @@ dependencies = [ [[package]] name = "ic-icrc1" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ciborium", @@ -3949,7 +3950,7 @@ dependencies = [ [[package]] name = "ic-icrc1-index-ng" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ciborium", @@ -3977,7 +3978,7 @@ dependencies = [ [[package]] name = "ic-icrc1-ledger" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -4005,7 +4006,7 @@ dependencies = [ [[package]] name = "ic-icrc1-tokens-u64" version = "0.1.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-ledger-core", @@ -4017,7 +4018,7 @@ dependencies = [ [[package]] name = "ic-interfaces" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-crypto-interfaces-sig-verification", @@ -4042,7 +4043,7 @@ dependencies = [ [[package]] name = "ic-interfaces-registry" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-types", "prost", @@ -4052,7 +4053,7 @@ dependencies = [ [[package]] name = "ic-interfaces-state-manager" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-tree-hash", "ic-types", @@ -4063,7 +4064,7 @@ dependencies = [ [[package]] name = "ic-ledger-canister-core" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -4081,7 +4082,7 @@ dependencies = [ [[package]] name = "ic-ledger-core" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-ledger-hash-of", @@ -4093,7 +4094,7 @@ dependencies = [ [[package]] name = "ic-ledger-hash-of" version = "0.1.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "hex", @@ -4103,7 +4104,7 @@ dependencies = [ [[package]] name = "ic-logger" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "chrono", "ic-config", @@ -4174,7 +4175,7 @@ dependencies = [ [[package]] name = "ic-management-canister-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-base-types", @@ -4218,7 +4219,7 @@ dependencies = [ [[package]] name = "ic-metrics" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "futures", "ic-adapter-metrics-client", @@ -4238,7 +4239,7 @@ checksum = "8b5c7628eac357aecda461130f8074468be5aa4d258a002032d82d817f79f1f8" [[package]] name = "ic-nervous-system-clients" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -4261,12 +4262,12 @@ dependencies = [ [[package]] name = "ic-nervous-system-collections-union-multi-map" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-nervous-system-common" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "base64 0.13.1", @@ -4302,12 +4303,12 @@ dependencies = [ [[package]] name = "ic-nervous-system-common-build-metadata" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-nervous-system-common-test-keys" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-canister-client-sender", @@ -4320,7 +4321,7 @@ dependencies = [ [[package]] name = "ic-nervous-system-governance" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-stable-structures", @@ -4332,12 +4333,12 @@ dependencies = [ [[package]] name = "ic-nervous-system-lock" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-nervous-system-proto" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "comparable", @@ -4350,7 +4351,7 @@ dependencies = [ [[package]] name = "ic-nervous-system-proxied-canister-calls-tracker" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", ] @@ -4358,7 +4359,7 @@ dependencies = [ [[package]] name = "ic-nervous-system-root" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "dfn_core", @@ -4374,7 +4375,7 @@ dependencies = [ [[package]] name = "ic-nervous-system-runtime" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -4387,17 +4388,17 @@ dependencies = [ [[package]] name = "ic-nervous-system-string" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-nervous-system-temporary" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-neurons-fund" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-nervous-system-common", "lazy_static", @@ -4410,7 +4411,7 @@ dependencies = [ [[package]] name = "ic-nns-common" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "comparable", @@ -4436,7 +4437,7 @@ dependencies = [ [[package]] name = "ic-nns-constants" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "maplit", @@ -4445,7 +4446,7 @@ dependencies = [ [[package]] name = "ic-nns-governance" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "build-info", @@ -4515,7 +4516,7 @@ dependencies = [ [[package]] name = "ic-nns-governance-api" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "bytes", "candid", @@ -4541,7 +4542,7 @@ dependencies = [ [[package]] name = "ic-nns-governance-init" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "csv", "ic-base-types", @@ -4558,12 +4559,12 @@ dependencies = [ [[package]] name = "ic-nns-gtc-accounts" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-nns-handler-root-interface" version = "0.1.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -4578,7 +4579,7 @@ dependencies = [ [[package]] name = "ic-protobuf" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "bincode", "candid", @@ -4592,7 +4593,7 @@ dependencies = [ [[package]] name = "ic-registry-canister-api" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-base-types", @@ -4603,7 +4604,7 @@ dependencies = [ [[package]] name = "ic-registry-client" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "crossbeam-channel", "ic-interfaces-registry", @@ -4616,7 +4617,7 @@ dependencies = [ [[package]] name = "ic-registry-client-fake" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-interfaces-registry", "ic-types", @@ -4625,7 +4626,7 @@ dependencies = [ [[package]] name = "ic-registry-client-helpers" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-interfaces-registry", @@ -4644,7 +4645,7 @@ dependencies = [ [[package]] name = "ic-registry-common-proto" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "prost", ] @@ -4652,7 +4653,7 @@ dependencies = [ [[package]] name = "ic-registry-keys" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-base-types", @@ -4664,7 +4665,7 @@ dependencies = [ [[package]] name = "ic-registry-local-registry" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-interfaces-registry", "ic-protobuf", @@ -4682,7 +4683,7 @@ dependencies = [ [[package]] name = "ic-registry-local-store" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-interfaces-registry", "ic-registry-common-proto", @@ -4694,12 +4695,12 @@ dependencies = [ [[package]] name = "ic-registry-local-store-artifacts" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-registry-nns-data-provider" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "chrono", "ic-canister-client", @@ -4719,7 +4720,7 @@ dependencies = [ [[package]] name = "ic-registry-provisional-whitelist" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-base-types", "ic-protobuf", @@ -4728,7 +4729,7 @@ dependencies = [ [[package]] name = "ic-registry-routing-table" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-base-types", @@ -4739,7 +4740,7 @@ dependencies = [ [[package]] name = "ic-registry-subnet-features" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-management-canister-types", @@ -4750,7 +4751,7 @@ dependencies = [ [[package]] name = "ic-registry-subnet-type" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-protobuf", @@ -4762,7 +4763,7 @@ dependencies = [ [[package]] name = "ic-registry-transport" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "ic-base-types", @@ -4774,7 +4775,7 @@ dependencies = [ [[package]] name = "ic-replicated-state" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "bit-vec", "cvt", @@ -4819,7 +4820,7 @@ dependencies = [ [[package]] name = "ic-sns-governance" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "base64 0.13.1", @@ -4876,7 +4877,7 @@ dependencies = [ [[package]] name = "ic-sns-governance-proposal-criticality" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-nervous-system-proto", ] @@ -4884,7 +4885,7 @@ dependencies = [ [[package]] name = "ic-sns-governance-proposals-amount-total-limit" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-sns-governance-token-valuation", "num-traits", @@ -4895,7 +4896,7 @@ dependencies = [ [[package]] name = "ic-sns-governance-token-valuation" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -4916,7 +4917,7 @@ dependencies = [ [[package]] name = "ic-sns-init" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "candid", @@ -4943,7 +4944,7 @@ dependencies = [ [[package]] name = "ic-sns-root" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "build-info", @@ -4972,7 +4973,7 @@ dependencies = [ [[package]] name = "ic-sns-swap" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "build-info", @@ -5010,7 +5011,7 @@ dependencies = [ [[package]] name = "ic-sns-swap-proto-library" version = "0.0.1" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "comparable", @@ -5025,7 +5026,7 @@ dependencies = [ [[package]] name = "ic-sns-wasm" version = "1.0.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -5072,7 +5073,7 @@ dependencies = [ [[package]] name = "ic-sys" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "cvt", "hex", @@ -5108,7 +5109,7 @@ dependencies = [ [[package]] name = "ic-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base64 0.13.1", "bincode", @@ -5143,7 +5144,7 @@ dependencies = [ [[package]] name = "ic-utils" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "hex", "scoped_threadpool", @@ -5176,7 +5177,7 @@ dependencies = [ [[package]] name = "ic-utils-thread" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "ic-verify-bls-signature" @@ -5212,7 +5213,7 @@ dependencies = [ [[package]] name = "ic-wasm-types" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-sha2", "ic-sys", @@ -5246,7 +5247,7 @@ checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf" [[package]] name = "ic0" version = "0.23.0" -source = "git+https://github.com/dfinity/cdk-rs.git?rev=deb1e15ae4c60333636f0581e0f30d169d8c9a0a#deb1e15ae4c60333636f0581e0f30d169d8c9a0a" +source = "git+https://github.com/dfinity/cdk-rs.git?rev=bd17d57a7b8ca59665fea5fad6143ca02724d03b#bd17d57a7b8ca59665fea5fad6143ca02724d03b" [[package]] name = "ic_bls12_381" @@ -5279,7 +5280,7 @@ dependencies = [ [[package]] name = "icp-ledger" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "comparable", @@ -5309,7 +5310,7 @@ dependencies = [ [[package]] name = "icrc-ledger-client" version = "0.1.2" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "async-trait", "candid", @@ -5320,7 +5321,7 @@ dependencies = [ [[package]] name = "icrc-ledger-types" version = "0.1.6" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "base32", "candid", @@ -5451,7 +5452,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -5682,9 +5683,9 @@ dependencies = [ [[package]] name = "keyring" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3ffeb4169230bc4f956b7276b688fc203824cc2ace8dc41ceecbd1746011a6" +checksum = "73b9af47ded4df3067484d7d45758ca2b36bd083bf6d024c2952bbd8af1cdaa4" [[package]] name = "language-tags" @@ -5709,9 +5710,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.156" +version = "0.2.157" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" +checksum = "374af5f94e54fa97cf75e945cce8a6b201e88a1a07e688b47dfd2a59c66dbd86" [[package]] name = "libflate" @@ -5996,14 +5997,13 @@ dependencies = [ [[package]] name = "mockall" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" +checksum = "d4c28b3fb6d753d28c20e826cd46ee611fda1cf3cde03a443a974043247c065a" dependencies = [ "cfg-if", "downcast", "fragile", - "lazy_static", "mockall_derive", "predicates", "predicates-tree", @@ -6011,14 +6011,14 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" +checksum = "341014e7f530314e9a1fdbc7400b244efea7122662c96bfa248c31da5bfb2020" dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -6359,7 +6359,7 @@ dependencies = [ [[package]] name = "on_wire" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" [[package]] name = "once_cell" @@ -6396,7 +6396,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -6642,7 +6642,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -6669,7 +6669,7 @@ dependencies = [ [[package]] name = "phantom_newtype" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "candid", "serde", @@ -6693,7 +6693,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -6820,7 +6820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -7015,7 +7015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", - "heck 0.5.0", + "heck 0.4.1", "itertools 0.12.1", "log", "multimap", @@ -7025,7 +7025,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.74", + "syn 2.0.75", "tempfile", ] @@ -7039,7 +7039,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -7096,6 +7096,7 @@ dependencies = [ "clap 4.5.16", "dirs", "dre", + "futures", "ic-canisters", "ic-management-backend", "ic-management-types", @@ -7332,7 +7333,7 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "registry-canister" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "build-info", "build-info-build", @@ -7559,7 +7560,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.74", + "syn 2.0.75", "unicode-ident", ] @@ -7925,7 +7926,7 @@ checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -7958,7 +7959,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -7981,7 +7982,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8289,10 +8290,10 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d1e02fca405f6280643174a50c942219f0bbf4dbf7d480f1dd864d6f211ae5" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8436,7 +8437,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8464,9 +8465,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", @@ -8482,7 +8483,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8505,7 +8506,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8630,7 +8631,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8656,7 +8657,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8733,9 +8734,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", @@ -8767,7 +8768,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8902,7 +8903,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -8978,7 +8979,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -9023,7 +9024,7 @@ dependencies = [ [[package]] name = "tree-deserializer" version = "0.9.0" -source = "git+https://github.com/dfinity/ic.git?rev=b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46#b4ccc86f84d6d6ffcd74eab706b0a0fed1607a46" +source = "git+https://github.com/dfinity/ic.git?rev=b0aef30f10784189a5ce73e58ed1f19359a5a3ae#b0aef30f10784189a5ce73e58ed1f19359a5a3ae" dependencies = [ "ic-crypto-tree-hash", "leb128", @@ -9038,14 +9039,12 @@ dependencies = [ "candid", "dfn_core", "futures", - "ic-base-types", "ic-cdk 0.15.0", "ic-cdk-macros 0.15.0", "ic-cdk-timers 0.9.0", "ic-management-canister-types", "ic-nns-common", "ic-protobuf", - "ic-registry-keys", "ic-stable-structures", "itertools 0.13.0", "trustworthy-node-metrics-types", @@ -9333,7 +9332,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", "wasm-bindgen-shared", ] @@ -9367,7 +9366,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9776,7 +9775,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", "synstructure", ] @@ -9798,7 +9797,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -9818,7 +9817,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", "synstructure", ] @@ -9839,7 +9838,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] @@ -9861,7 +9860,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.75", ] [[package]] From 9ab3cd455e47c83f86cdcf679a99a52393ffdef4 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 20 Aug 2024 19:41:52 +0200 Subject: [PATCH 32/40] Cargo lock update --- Cargo.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index aab53a540..32c566a47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9039,12 +9039,14 @@ dependencies = [ "candid", "dfn_core", "futures", + "ic-base-types", "ic-cdk 0.15.0", "ic-cdk-macros 0.15.0", "ic-cdk-timers 0.9.0", "ic-management-canister-types", "ic-nns-common", "ic-protobuf", + "ic-registry-keys", "ic-stable-structures", "itertools 0.13.0", "trustworthy-node-metrics-types", From b2f43fbc51066542cd1d3de7d8738369e7b4c044 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 20 Aug 2024 17:45:52 +0000 Subject: [PATCH 33/40] Github Action: Bazel Repin --- Cargo.Bazel.lock | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 1652f1f01..ef4f10d1f 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "ea5dd38d60356ea002de789a5eb67763d68cb6b2e016ed921f20e9c61a9b1d9d", + "checksum": "65890af6a96379e8bf9cadc28d9809e75af72e7e5d2127b2b888fe28d05ebc42", "crates": { "actix-codec 0.5.2": { "name": "actix-codec", @@ -45348,6 +45348,10 @@ "id": "futures 0.3.30", "target": "futures" }, + { + "id": "ic-base-types 0.9.0", + "target": "ic_base_types" + }, { "id": "ic-cdk 0.15.0", "target": "ic_cdk" @@ -45368,6 +45372,10 @@ "id": "ic-protobuf 0.9.0", "target": "ic_protobuf" }, + { + "id": "ic-registry-keys 0.9.0", + "target": "ic_registry_keys" + }, { "id": "ic-stable-structures 0.6.5", "target": "ic_stable_structures" From 2944f619fcd26236a3a57cd11dea2d942abe4dd0 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 20 Aug 2024 19:47:57 +0200 Subject: [PATCH 34/40] Fixed clippy --- .../src/trustworthy-node-metrics/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs index f4a896418..c908ec871 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/lib.rs @@ -3,7 +3,8 @@ use ic_cdk_macros::*; use itertools::Itertools; use std::collections::{self, btree_map::Entry, BTreeMap}; use trustworthy_node_metrics_types::types::{ - DailyNodeMetrics, NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, SubnetNodeMetricsResponse + DailyNodeMetrics, NodeMetrics, NodeMetricsStored, NodeMetricsStoredKey, NodeRewardsArgs, NodeRewardsResponse, SubnetNodeMetricsArgs, + SubnetNodeMetricsResponse, }; mod metrics_manager; mod rewards_manager; From 438bbdf9042d840c339f26c28c7259de627c9863 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 20 Aug 2024 19:49:40 +0200 Subject: [PATCH 35/40] Fixed rustfmt --- .../src/trustworthy-node-metrics/src/metrics_manager.rs | 8 +------- .../src/trustworthy-node-metrics/src/stable_memory.rs | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs index 43e3dae46..ad2aa9495 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/metrics_manager.rs @@ -122,13 +122,7 @@ async fn fetch_node_provider(node_id: &PrincipalId) -> anyhow::Result(node_record_key.as_bytes(), None) .await - .map_err(|e| { - anyhow!( - "Error getting the node_record from the registry for node {}. Error: {:?}", - node_id, - e - ) - })?; + .map_err(|e| anyhow!("Error getting the node_record from the registry for node {}. Error: {:?}", node_id, e))?; let node_operator_id: PrincipalId = node_record.node_operator_id.try_into()?; let node_operator_key = make_node_operator_record_key(node_operator_id); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs index 47d6d3c75..023af6f18 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/src/stable_memory.rs @@ -58,6 +58,6 @@ pub fn insert_node_provider(key: Principal, value: Principal) { NODE_PROVIDER_MAP.with(|p| p.borrow_mut().insert(key, value)); } -pub(crate) fn get_node_provider(node_principal: &Principal) -> Option { +pub fn get_node_provider(node_principal: &Principal) -> Option { NODE_PROVIDER_MAP.with_borrow(|np_map| np_map.get(node_principal)) } From 70a53532cc6881b8c10d422471a6bfb171b60f21 Mon Sep 17 00:00:00 2001 From: Pietro Date: Thu, 22 Aug 2024 17:29:20 +0200 Subject: [PATCH 36/40] Add node Machine Page --- dashboard/packages/app/src/App.tsx | 5 + .../trustworthy-node-metrics/args-rewards.bin | 4 + .../trustworthy-node-metrics/args.bin | 4 + .../pool_logs.sh | 0 .../index.html | 2 +- .../src/App.tsx | 104 +++++----- .../src/Styles.tsx | 32 +++ .../src/components/DailyPerformanceChart.tsx | 111 ++++++++++ .../src/components/Drawer.tsx | 107 +++++----- .../src/components/FilterBar.tsx | 31 +-- .../src/components/Gauge.tsx | 63 ------ .../src/components/Header.tsx | 18 +- .../src/components/NodeChart.tsx | 74 +++++++ .../src/components/NodeInfo.tsx | 29 +++ .../src/components/NodeList.tsx | 194 +++++++----------- .../src/components/RewardTable.tsx | 17 +- .../src/components/SubnetChart.tsx | 22 +- .../src/components/Widgets.tsx | 70 +++++++ .../src/index.scss | 15 ++ .../src/models/NodeMetrics.tsx | 30 --- .../src/utils/utils.tsx | 8 +- 21 files changed, 589 insertions(+), 351 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin create mode 100644 rs/dre-canisters/trustworthy-node-metrics/args.bin rename rs/dre-canisters/trustworthy-node-metrics/{src/trustworthy-node-metrics => }/pool_logs.sh (100%) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/DailyPerformanceChart.tsx delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeInfo.tsx create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx diff --git a/dashboard/packages/app/src/App.tsx b/dashboard/packages/app/src/App.tsx index 80b3d2dc1..3b167cef3 100644 --- a/dashboard/packages/app/src/App.tsx +++ b/dashboard/packages/app/src/App.tsx @@ -118,6 +118,11 @@ const routes = ( ); const StateRefresh = ({ children }: { children: React.ReactNode }) => { + + + + + let { data: version } = useQuery(`${get_network()}_version`, async () => await fetchVersion().then((res) => res.json()) , { diff --git a/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin new file mode 100644 index 000000000..16769a168 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/args-rewards.bin @@ -0,0 +1,4 @@ +(record { + from_ts = 0; + to_ts = 1723507199978493357; +}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/args.bin b/rs/dre-canisters/trustworthy-node-metrics/args.bin new file mode 100644 index 000000000..96a0634b7 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/args.bin @@ -0,0 +1,4 @@ +(record { + subnet_id = opt principal "tfiqy-cbhk2-fkeq5-5p5r5-kk7eg-kctmo-tfaor-jogn2-ouxpw-un4kh-kqe"; + ts = opt 0; +}) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/pool_logs.sh b/rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh similarity index 100% rename from rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics/pool_logs.sh rename to rs/dre-canisters/trustworthy-node-metrics/pool_logs.sh diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html index c1d49e2de..192c20f4e 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/index.html @@ -4,7 +4,7 @@ - Node Rewards App + Node Provider Rewards diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index 6043cf723..941d0e826 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { Box, CircularProgress, CssBaseline, ThemeProvider, createTheme } from '@mui/material'; import FilterBar, { PeriodFilter } from './components/FilterBar'; import Drawer from './components/Drawer'; @@ -10,14 +10,30 @@ import { NodeList } from './components/NodeList'; import Header from './components/Header'; import { dateToNanoseconds } from './utils/utils'; import { SubnetChart } from './components/SubnetChart'; +import { NodeChart } from './components/NodeChart'; +// Theme configuration const darkTheme = createTheme({ palette: { mode: 'dark', - divider: '#121212', + primary: { + main: '#3f51b5', + }, + secondary: { + main: '#f50057', + }, }, }); +const getDateRange = () => { + const dateStart = new Date(); + const dateEnd = new Date(); + dateStart.setDate(dateStart.getDate() - 30); + dateStart.setHours(0, 0, 0, 0); + dateEnd.setHours(23, 59, 59, 999); + return { dateStart, dateEnd }; +}; + const LoadingIndicator: React.FC = () => ( ( ); -function App() { - const dateStart = new Date(); - const dateEnd = new Date(); - dateStart.setDate(dateStart.getDate() - 30); - dateStart.setHours(0, 0, 0, 0); - dateEnd.setHours(23, 59, 59, 999); - - const [periodFilter, setPeriodFilter] = useState({ - dateStart: dateStart, - dateEnd: dateEnd - }); - - const [dashboardNodeRewards, setDashboardNodeRewards] = useState([]); - +const App: React.FC = () => { + const { dateStart, dateEnd } = useMemo(() => getDateRange(), []); + + const [periodFilter, setPeriodFilter] = useState({ dateStart, dateEnd }); + const [nodeRewards, setNodeRewards] = useState([]); const [subnets, setSubnets] = useState>(new Set()); const [nodeProviders, setNodeProviders] = useState>(new Set()); + const [drawerOpen, setDrawerOpen] = useState(false); const [isLoading, setIsLoading] = useState(true); const drawerWidth = 180; useEffect(() => { const updateRewards = async () => { try { - setIsLoading(true) + setIsLoading(true); const request: NodeRewardsArgs = { from_ts: dateToNanoseconds(periodFilter.dateStart), to_ts: dateToNanoseconds(periodFilter.dateEnd), }; - const nodeRewardsResponse: NodeRewardsResponse[] = await trustworthy_node_metrics.node_rewards(request); - - const dashboardNodeRewards = nodeRewardsResponse.map((nodeRewards) => { - return new DashboardNodeRewards( - nodeRewards.node_id, - nodeRewards.daily_node_metrics, - nodeRewards.rewards_no_penalty, - nodeRewards.rewards_with_penalty, - ); - }).sort((a, b) => a.rewardsNoPenalty - b.rewardsNoPenalty ); + const nodeRewardsResponse = await trustworthy_node_metrics.node_rewards(request); + const sortedNodeRewards = nodeRewardsResponse.sort((a, b) => a.rewards_percent - b.rewards_percent); + const subnets = new Set(sortedNodeRewards.flatMap(node => node.daily_node_metrics.map(data => data.subnet_assigned.toText()))); - - const subnets = new Set(dashboardNodeRewards.flatMap(nodeRewards => nodeRewards.dailyData.map( data => data.subnet_assigned.toText()))); - - setDashboardNodeRewards(dashboardNodeRewards); + setNodeRewards(sortedNodeRewards); setSubnets(subnets); - } catch (error) { console.error("Error fetching node:", error); } finally { @@ -85,36 +82,37 @@ function App() { updateRewards(); }, [periodFilter]); + const handleDrawerToggle = () => setDrawerOpen(prev => !prev); + + const drawerProps = useMemo(() => ({ + subnets, + nodeProviders, + drawerWidth, + open: drawerOpen, + onClose: () => setDrawerOpen(false), + }), [subnets, nodeProviders, drawerWidth, drawerOpen]); + return ( - - -
- - - + + +
+ + } /> ) : ()} - /> + isLoading ? : + } /> + : + } /> ) : ()} - /> + isLoading ? : + } /> diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx new file mode 100644 index 000000000..8158b8ab6 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx @@ -0,0 +1,32 @@ +import { SxProps, Theme } from '@mui/material'; + +export const paperStyle: SxProps = { + bgcolor: 'background.paper', + borderRadius: '10px', + p: 2, +}; + +export const boxStyleLeft: SxProps = { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'left', + gap: 2, +}; + +export const boxStyleRight: SxProps = { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'right', + alignItems: 'left', + gap: 2, +}; + +export const paperStyleWidget: SxProps = { + p: 2, + display: 'flex', + flexDirection: 'row', + alignItems: 'right', + width: '250px', + bgcolor: 'background.paper', + borderRadius: '10px' + }; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/DailyPerformanceChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/DailyPerformanceChart.tsx new file mode 100644 index 000000000..4e47ed20f --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/DailyPerformanceChart.tsx @@ -0,0 +1,111 @@ +import React from 'react'; +import Typography from '@mui/material/Typography'; +import { + BarPlot, + LinePlot, + MarkPlot, + ChartsAxisHighlight, + ChartsTooltip, + ChartsLegend, + ChartsXAxis, + ChartsYAxis, + ResponsiveChartContainer +} from '@mui/x-charts'; // Update paths +import { ChartData } from '../utils/utils'; + +interface DailyPerformanceChartProps { + chartDailyData: ChartData[]; +} + +const DailyPerformanceChart: React.FC = ({ chartDailyData }) => { + const maxBlocks = Math.max( + ...chartDailyData.map(entry => entry.dailyNodeMetrics ? + Number(entry.dailyNodeMetrics.num_blocks_proposed + entry.dailyNodeMetrics.num_blocks_failed) : 0) + ); + const xAxisConfig = [ + { + id: 'x-axis-id', + scaleType: 'band' as const, + dataKey: 'date', + valueFormatter: (value: Date) => value + .toLocaleDateString('UTC', { month: 'short', day: 'numeric' }) + .replace(" ", "\n"), + } + ]; + + const yAxisConfig = [ + { + id: 'y-axis-id', + valueFormatter: (value: number) => `${value}`, + } + ]; + + const seriesConfig = [ + { + dataKey: 'blocksProposed', + label: 'Proposed Blocks', + color: '#4CAF79', + stack: 'total', + type: 'bar' as const, + valueFormatter: (value: number | null) => value ? `${value}` : '0', + }, + { + dataKey: 'blocksFailed', + label: 'Failed Blocks', + color: '#FF6347', + stack: 'total', + type: 'bar' as const, + valueFormatter: (value: number | null) => value ? `${value}` : '0', + }, + { + dataKey: 'unassigned', + label: 'Unassigned', + color: 'white', + area: true, + stack: 'total', + type: 'line' as const, + valueFormatter: (value: number | null) => (value ? 'Yes' : ''), + } + ]; + + const dataset = chartDailyData.map((entry) => ({ + date: entry.date, + blocksProposed: entry.dailyNodeMetrics ? Number(entry.dailyNodeMetrics.num_blocks_proposed) : null, + blocksFailed: entry.dailyNodeMetrics ? Number(entry.dailyNodeMetrics.num_blocks_failed) : null, + unassigned: entry.dailyNodeMetrics ? null : maxBlocks / 2, + })); + + const legendConfig = { + legend: { + direction: 'row' as const, + position: { vertical: 'top', horizontal: 'right' } as const, + padding: 0, + }, + }; + + return ( +
+ + Daily Performance + + + + + + + + + + + +
+ ); +}; + +export default DailyPerformanceChart; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx index 8584f318c..ef7305710 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Drawer.tsx @@ -8,6 +8,8 @@ import { IconButton, ListItem, Toolbar, + useMediaQuery, + useTheme, } from '@mui/material'; import { Link } from 'react-router-dom'; import Logo from '../assets/icp_logo.svg'; @@ -17,66 +19,77 @@ interface DrawerProps { subnets: Set; nodeProviders: Set; drawerWidth: number; + open: boolean; + onClose: () => void; } -const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth }) => { - const [openSubnets, setOpenSubnets] = React.useState(false); - const [openNP, setOpenNp] = React.useState(false); +const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth, open, onClose }) => { + const [isSubnetsOpen, setIsSubnetsOpen] = React.useState(false); + const [isNodeProvidersOpen, setIsNodeProvidersOpen] = React.useState(false); + + const theme = useTheme(); + const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); const renderCollapsibleList = ( title: string, items: Set, - open: boolean, - setOpen: React.Dispatch>, + isOpen: boolean, + toggleOpen: React.Dispatch>, basePath: string - ) => ( - <> - setOpen(!open)}> - - {open ? : } - - - - {Array.from(items).map((item, index) => ( - - - - - - ))} - - - - ); + ) => { + const itemList = items ? Array.from(items) : []; + + return ( + <> + toggleOpen(!isOpen)}> + + {isOpen ? : } + + + + {itemList.map((item, index) => ( + + + + + + ))} + + + + ); + }; return ( - - - + + Logo - - - - - - - - {renderCollapsibleList("Subnets", subnets, openSubnets, setOpenSubnets, "subnets")} - {renderCollapsibleList("Node Providers", nodeProviders, openNP, setOpenNp, "node-providers")} - - + + + + + + + + {renderCollapsibleList("Subnets", subnets, isSubnetsOpen, setIsSubnetsOpen, "subnets")} + {renderCollapsibleList("Node Providers", nodeProviders, isNodeProvidersOpen, setIsNodeProvidersOpen, "node-providers")} + + ); }; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx index fa9702bc3..0a1246463 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/FilterBar.tsx @@ -1,10 +1,9 @@ import React from 'react'; -import { Toolbar } from '@mui/material'; +import { Toolbar, Box } from '@mui/material'; import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; -// Define the types for props export interface PeriodFilter { dateStart: Date; dateEnd: Date; @@ -13,40 +12,44 @@ export interface PeriodFilter { interface FilterBarProps { filters: PeriodFilter; setFilters: React.Dispatch>; - subnets: Set | null; // Use string instead of String } const FilterBar: React.FC = ({ filters, setFilters }) => { const handleDateStartChange = (newValue: Date | null) => { - if (newValue !== null) { - setFilters((prev) => ({ ...prev, dateStart: newValue })); - } + setFilters(prev => ({ + ...prev, + dateStart: newValue ?? prev.dateStart, + })); }; const handleDateEndChange = (newValue: Date | null) => { - if (newValue !== null) { - setFilters((prev) => ({ ...prev, dateEnd: newValue })); - } + setFilters(prev => ({ + ...prev, + dateEnd: newValue ?? prev.dateEnd, + })); }; return ( - - + + + - - + + + ); }; - export default FilterBar; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx deleted file mode 100644 index aa294ce32..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Gauge.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Box, Typography } from '@mui/material'; -import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; -import React from 'react'; - -export default function FailureRateArc(value: number) { - return ( - - - Failure Rate - - `${value}%` - } - sx={(theme) => ({ - [`& .${gaugeClasses.valueText}`]: { - fontSize: 15, - }, - [`& .${gaugeClasses.valueArc}`]: { - fill: '#FF6347', - }, - [`& .${gaugeClasses.referenceArc}`]: { - fill: theme.palette.text.disabled, - }, - })} - /> - - ); -} - -export function RewardsArc(value: number, title: string) { - return ( - - - {title} - - `${value}%` - } - sx={(theme) => ({ - [`& .${gaugeClasses.valueText}`]: { - fontSize: 15, - }, - [`& .${gaugeClasses.valueArc}`]: { - fill: '#52b202', - }, - [`& .${gaugeClasses.referenceArc}`]: { - fill: theme.palette.text.disabled, - }, - })} - /> - - ); -} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx index 1753db077..a17e6c1a3 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Header.tsx @@ -1,5 +1,6 @@ -import { Toolbar, Typography, styled } from '@mui/material'; +import { IconButton, Toolbar, Typography, styled, useMediaQuery, useTheme } from '@mui/material'; import React from 'react'; +import { Menu as MenuIcon } from '@mui/icons-material'; const Title = styled(Typography)(() => ({ flexGrow: 1, @@ -10,12 +11,23 @@ const Title = styled(Typography)(() => ({ color: 'white' })); +interface HeaderProps { + onDrawerToggle: () => void; +} -const Header = () => { +const Header: React.FC = ({ onDrawerToggle }) => { + const theme = useTheme(); + const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); + return ( + {isSmallScreen && ( + + + + )} - Node Rewards + Node Provider Rewards ); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx new file mode 100644 index 000000000..e381443aa --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { ChartData, generateChartData } from '../utils/utils'; +import { WidgetGauge, WidgetNumber } from './Widgets'; +import { PeriodFilter } from './FilterBar'; +import { Box, Grid, Paper, Typography } from '@mui/material'; +import { useParams } from 'react-router-dom'; +import DailyPerformanceChart from './DailyPerformanceChart'; +import NodeInfo from './NodeInfo'; +import { paperStyle, boxStyleLeft, boxStyleRight } from '../Styles'; +import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; + +export interface NodeChartProps { + nodeRewards: NodeRewardsResponse[]; + periodFilter: PeriodFilter; +} + +const NodeMetricsStats: React.FC<{ stats: NodeRewardsResponse['rewards_stats'] }> = ({ stats }) => ( + + + + +); + +const NodePerformanceStats: React.FC<{ failureRateAvg: string, rewardPercent: string }> = ({ failureRateAvg, rewardPercent }) => ( + + + + + +); + +export const NodeChart: React.FC = ({ nodeRewards, periodFilter }) => { + const { node } = useParams(); + + const nodeMetrics = nodeRewards.find((metrics) => metrics.node_id.toText() === node); + if (!nodeMetrics) { + return

Node metrics not found

; + } + + const chartDailyData: ChartData[] = generateChartData(periodFilter, nodeMetrics.daily_node_metrics); + const failureRateAvg = `${Math.round(nodeMetrics.rewards_stats.failure_rate * 100)}%`; + const rewardPercent = `${Math.round(nodeMetrics.rewards_percent * 100)}%`; + + return ( + + + + + + {"Node Machine"} + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default NodeChart; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeInfo.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeInfo.tsx new file mode 100644 index 000000000..2311b46a5 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeInfo.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import Typography from '@mui/material/Typography'; + +interface NodeInfoProps { + nodeId: string; + nodeProviderId: string; +} + +const NodeInfo: React.FC = ({ nodeId, nodeProviderId }) => { + return ( +
+ + {"Node ID"} + + + {nodeId} + + + + {"Node Provider ID"} + + + {nodeProviderId} + +
+ ); +}; + +export default NodeInfo; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx index 348e43e29..6caa20b69 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeList.tsx @@ -1,131 +1,93 @@ -import React, { useState } from 'react'; -import { Box, Grid, Paper, Typography, Autocomplete, TextField } from '@mui/material'; -import { axisClasses, BarChart } from '@mui/x-charts'; -import { ChartData, DashboardNodeRewards } from '../models/NodeMetrics'; +import React, { useState, useEffect } from 'react'; +import { Box, Autocomplete, TextField, TableCell, TableRow, TableHead, Table, TableContainer, Paper, TableBody } from '@mui/material'; +import { Link } from 'react-router-dom'; import { styled } from '@mui/material/styles'; -import Divider from '@mui/material/Divider'; import { PeriodFilter } from './FilterBar'; -import { generateChartData} from '../utils/utils'; -import FailureRateArc, { RewardsArc } from './Gauge'; -import { Principal } from '@dfinity/principal'; -import { DailyNodeMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; +import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; export const Root = styled('div')(({ theme }) => ({ - width: '100%', - ...theme.typography.body2, - color: theme.palette.text.secondary, - '& > :not(style) ~ :not(style)': { - marginTop: theme.spacing(2), - }, + width: '100%', + ...theme.typography.body2, + color: theme.palette.text.secondary, + '& > :not(style) ~ :not(style)': { + marginTop: theme.spacing(2), + }, })); export interface NodeListProps { - dashboardNodeMetrics: DashboardNodeRewards[], - periodFilter: PeriodFilter + nodeRewards: NodeRewardsResponse[]; + periodFilter: PeriodFilter; } -function renderChart( - nodeId: Principal, - dailyData: DailyNodeMetrics[], - failureRateAvg: number, - rewardsNoPenalty: number, - rewardsWithPenalty: number, - periodFilter: PeriodFilter): React.ReactNode { +const tableHeaders = [ + { label: 'Node ID', key: 'node_id' }, + { label: 'Node Provider ID', key: 'node_provider_id' }, + { label: 'Days Assigned', key: 'days_assigned' }, + { label: 'Rewards Percent', key: 'rewards_percent' }, + { label: 'Failure Rate Avg.', key: 'failure_rate' }, +]; - const chartDailyData: ChartData[] = generateChartData(periodFilter, dailyData); +export const NodeList: React.FC = ({ nodeRewards }) => { + const [filteredMetrics, setFilteredMetrics] = useState(nodeRewards); - return ( - - - - {nodeId.toText()} - - - {FailureRateArc(failureRateAvg)} - {RewardsArc(rewardsNoPenalty, 'Rewards No Penalty')} - {RewardsArc(rewardsWithPenalty, 'Rewards With Penalty')} - - - - - value.toLocaleDateString('UTC', { month: 'short', day: 'numeric' }).replace(" ", "\n") - }]} - yAxis={[ - { - valueFormatter: value => `${value}%`, - min: 0, - max: 100, - }, - ]} - series={[ - { dataKey: 'failureRate', label: "Failure Rate", color: '#FF6347', - valueFormatter: (value: number | null) => value ? `${value}%` : 'Not assigned' }, - ]} - dataset={chartDailyData.map(entry => ({ - date: entry.date, - failureRate: entry.failureRate, - }))} + useEffect(() => { + setFilteredMetrics(nodeRewards); + }, [nodeRewards]); - height={400} - /> - - - ) -} - -export const NodeList: React.FC = ({ dashboardNodeMetrics, periodFilter }) => { - const [prevItems, setPrevItems] = useState(dashboardNodeMetrics); - const [filteredMetrics, setFilteredMetrics] = useState(prevItems); + const handleSearchChange = (event: React.SyntheticEvent, value: string | null) => { + if (value) { + setFilteredMetrics(nodeRewards.filter(node => node.node_id.toText().includes(value))); + } else { + setFilteredMetrics(nodeRewards); + } + }; - if (dashboardNodeMetrics !== prevItems) { - setPrevItems(dashboardNodeMetrics); - setFilteredMetrics(dashboardNodeMetrics) - } - - const handleSearchChange = (event: unknown, value: string | null) => { - if (value) { - const filtered = dashboardNodeMetrics.filter(node => node.nodeId.toText().includes(value)); - setFilteredMetrics(filtered); - } else { - setFilteredMetrics(dashboardNodeMetrics); - } - }; - - return ( - - - - node.nodeId.toText())} - onInputChange={handleSearchChange} - renderInput={(params) => ( - - )} - /> - - - {filteredMetrics.slice(0, 20).map( - ({ nodeId, dailyData, failureRateAvg, rewardsNoPenalty, rewardsWithPenalty }, index) => ( - - {renderChart(nodeId, dailyData, failureRateAvg, rewardsNoPenalty, rewardsWithPenalty, periodFilter)} - + return ( + <> + + node.node_id.toText())} + onInputChange={handleSearchChange} + renderInput={(params) => ( + + )} + /> + + + + + + + + {tableHeaders.map(header => ( + {header.label} + ))} + + + + {filteredMetrics.map(nodeMetrics => ( + + + + {nodeMetrics.node_id.toText()} + + + {nodeMetrics.node_provider_id.toText()} + {nodeMetrics.daily_node_metrics.length} + {Math.round(nodeMetrics.rewards_percent * 100)}% + {Math.round(nodeMetrics.rewards_stats.failure_rate * 100)}% + ))} - - - - ); + +
+
+
+
+ + ); }; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx index 155fe417b..f54d43f14 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardTable.tsx @@ -6,15 +6,15 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Paper from '@mui/material/Paper'; -import { DashboardNodeRewards } from '../models/NodeMetrics'; import { SxProps, Theme } from '@mui/material'; +import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; interface RewardTableProps { - dashboardNodeMetrics: DashboardNodeRewards[], + nodeRewards: NodeRewardsResponse[], sx?: SxProps; } -const RewardTable: React.FC = ({ dashboardNodeMetrics }) => { +const RewardTable: React.FC = ({ nodeRewards }) => { return ( @@ -26,19 +26,16 @@ const RewardTable: React.FC = ({ dashboardNodeMetrics }) => { - {dashboardNodeMetrics.map((nodeMetrics) => ( + {nodeRewards.map((nodeMetrics) => ( - {nodeMetrics.nodeId.toText()} + {nodeMetrics.node_id.toText()} - {Math.round(nodeMetrics.failureRateAvg * 100)}% - - - {Math.round(nodeMetrics.rewardsNoPenalty * 100)}% + {Math.round(nodeMetrics.rewards_stats.failure_rate * 100)}% ))} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx index c50310be2..2deceb0cc 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx @@ -5,26 +5,26 @@ import Divider from '@mui/material/Divider'; import { useParams } from 'react-router-dom'; import { generateChartData, getFormattedDates } from '../utils/utils'; import RewardTable from './RewardTable'; -import { DashboardNodeRewards } from '../models/NodeMetrics'; import { PeriodFilter } from './FilterBar'; import { Root } from './NodeList'; +import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; export interface SubnetChartProps { - dashboardNodeMetrics: DashboardNodeRewards[], + nodeRewards: NodeRewardsResponse[], periodFilter: PeriodFilter } -export const SubnetChart: React.FC = ({ dashboardNodeMetrics, periodFilter }) => { +export const SubnetChart: React.FC = ({ nodeRewards, periodFilter }) => { const [stackOrder] = useState('ascending'); const { subnet } = useParams(); - const subnetNodeMetrics = dashboardNodeMetrics - .filter((nodeMetrics) => nodeMetrics.dailyData.some((daily) => daily.subnet_assigned.toText() === subnet)) - const chartData = subnetNodeMetrics - .filter((nodeMetrics) => nodeMetrics.dailyData.some(data => data.failure_rate >= 0.1)) + const subnetNodeMetrics = nodeRewards + .filter((nodeMetrics) => nodeMetrics.daily_node_metrics.some((daily) => daily.subnet_assigned.toText() === subnet)) + const chartData = nodeRewards + .filter((nodeMetrics) => nodeMetrics.daily_node_metrics.some(data => data.failure_rate >= 0.1)) .map(nodeMetrics => { return { - data: generateChartData(periodFilter, nodeMetrics.dailyData).map(daily => daily.failureRate), - label: nodeMetrics.nodeId.toText(), + data: generateChartData(periodFilter, nodeMetrics.daily_node_metrics).map(daily => 3), + label: nodeMetrics.node_id.toText(), } }); @@ -33,7 +33,7 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, return ( - + Subnet: {subnet} @@ -67,7 +67,7 @@ export const SubnetChart: React.FC = ({ dashboardNodeMetrics, height={500} /> - + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx new file mode 100644 index 000000000..977168796 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx @@ -0,0 +1,70 @@ +import { Box, Paper, Stack, Typography } from '@mui/material'; +import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; +import { boxStyleRight, paperStyleWidget } from '../Styles'; + +import React from 'react'; + +export function WidgetNumber({ value, title }: { value: string, title: string }) { + return ( + + + + {value} + + + {title} + + + + ); +} +export function WidgetGauge({ value, title }: { value: number, title: string }) { + return ( + + + + + `${value}%`} + sx={(theme) => ({ + [`& .${gaugeClasses.valueText}`]: { + fontSize: 20, + }, + [`& .${gaugeClasses.valueArc}`]: { + fill: '#52b202', + }, + [`& .${gaugeClasses.referenceArc}`]: { + fill: theme.palette.text.disabled, + }, + })} + /> + + {title} + + + + + ); +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss index cc9943de1..c45f9ab2e 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/index.scss @@ -19,3 +19,18 @@ form { margin: auto; align-items: baseline; } + +.custom-link { + text-decoration: none; + color: rgb(113, 113, 246); +} + +.custom-link:hover { + color: rgb(44, 44, 191); +} + +.custom-paper { + background-color: #11171E; + border-radius: 10px; + color: white; +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx deleted file mode 100644 index e7e910e6f..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/models/NodeMetrics.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { DailyNodeMetrics } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; -import { computeAverageFailureRate } from '../utils/utils'; -import { Principal } from '@dfinity/principal'; -export interface ChartData { - date: Date ; - failureRate: number | null; -} - -export class DashboardNodeRewards { - nodeId: Principal; - nodeIdSmall: string; - dailyData: DailyNodeMetrics[]; - failureRateAvg: number; - rewardsNoPenalty: number; - rewardsWithPenalty: number; - - constructor( - nodeId: Principal, - dailyData: DailyNodeMetrics[], - rewardsNoPenalty: number, - rewardsWithPenalty: number, - ) { - this.nodeId = nodeId; - this.nodeIdSmall = nodeId.toText().split('-')[0]; - this.dailyData = dailyData; - this.failureRateAvg = computeAverageFailureRate(dailyData.map(elem => elem.failure_rate)); - this.rewardsNoPenalty = rewardsNoPenalty; - this.rewardsWithPenalty = rewardsWithPenalty; - } -} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx index b62c59fd0..ee763dc19 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/utils/utils.tsx @@ -1,7 +1,9 @@ import { DailyNodeMetrics } from "../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did"; import { PeriodFilter } from "../components/FilterBar"; -import { ChartData } from "../models/NodeMetrics"; - +export interface ChartData { + date: Date ; + dailyNodeMetrics: DailyNodeMetrics | null; +} export const dateToNanoseconds = (date: Date): bigint => { const millisecondsSinceEpoch = date.getTime(); @@ -26,7 +28,7 @@ export const generateChartData = (periodFilter: PeriodFilter, dailyData: DailyNo chartData.push({ date: new Date(currentDate), - failureRate: dailyDataEntry ? dailyDataEntry.failure_rate * 100 : null, + dailyNodeMetrics: dailyDataEntry ? dailyDataEntry : null, }); currentDate.setDate(currentDate.getDate() + 1); From 92774440a233083a5dff36a8d3db02c56788ba8f Mon Sep 17 00:00:00 2001 From: Pietro Date: Thu, 22 Aug 2024 17:38:49 +0200 Subject: [PATCH 37/40] Box style widget --- .../src/Styles.tsx | 15 ++++----------- .../src/components/NodeChart.tsx | 6 +++--- .../src/components/Widgets.tsx | 4 ++-- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx index 8158b8ab6..f3a990aec 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/Styles.tsx @@ -6,20 +6,13 @@ export const paperStyle: SxProps = { p: 2, }; -export const boxStyleLeft: SxProps = { +export const boxStyleWidget = (justifyContent: 'left' | 'right', alignItems?: 'flex-start' | 'center' | 'flex-end'): SxProps => ({ display: 'flex', flexWrap: 'wrap', - justifyContent: 'left', + justifyContent: justifyContent, + alignItems: alignItems || 'stretch', gap: 2, -}; - -export const boxStyleRight: SxProps = { - display: 'flex', - flexWrap: 'wrap', - justifyContent: 'right', - alignItems: 'left', - gap: 2, -}; +}); export const paperStyleWidget: SxProps = { p: 2, diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx index e381443aa..93f2d6329 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx @@ -6,7 +6,7 @@ import { Box, Grid, Paper, Typography } from '@mui/material'; import { useParams } from 'react-router-dom'; import DailyPerformanceChart from './DailyPerformanceChart'; import NodeInfo from './NodeInfo'; -import { paperStyle, boxStyleLeft, boxStyleRight } from '../Styles'; +import { paperStyle, boxStyleWidget } from '../Styles'; import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; export interface NodeChartProps { @@ -15,14 +15,14 @@ export interface NodeChartProps { } const NodeMetricsStats: React.FC<{ stats: NodeRewardsResponse['rewards_stats'] }> = ({ stats }) => ( - + ); const NodePerformanceStats: React.FC<{ failureRateAvg: string, rewardPercent: string }> = ({ failureRateAvg, rewardPercent }) => ( - + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx index 977168796..91345d827 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx @@ -1,6 +1,6 @@ import { Box, Paper, Stack, Typography } from '@mui/material'; import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; -import { boxStyleRight, paperStyleWidget } from '../Styles'; +import { boxStyleWidget, paperStyleWidget } from '../Styles'; import React from 'react'; @@ -24,7 +24,7 @@ export function WidgetNumber({ value, title }: { value: string, title: string }) export function WidgetGauge({ value, title }: { value: number, title: string }) { return ( Date: Thu, 22 Aug 2024 17:39:49 +0200 Subject: [PATCH 38/40] Modify rewards total --- .../src/components/Widgets.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx index 91345d827..e4a0c928f 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/Widgets.tsx @@ -35,7 +35,7 @@ export function WidgetGauge({ value, title }: { value: number, title: string }) alignItems: 'center', justifyContent: 'center', width: '150px', - height: '180px', + height: '160px', bgcolor: 'background.paper', borderRadius: '10px' }} From 7f88b63db15f968fe30a0c0012b909bd80c75edc Mon Sep 17 00:00:00 2001 From: Pietro Date: Thu, 22 Aug 2024 17:41:50 +0200 Subject: [PATCH 39/40] Revert changes to dashboard --- dashboard/packages/app/src/App.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dashboard/packages/app/src/App.tsx b/dashboard/packages/app/src/App.tsx index 3b167cef3..80b3d2dc1 100644 --- a/dashboard/packages/app/src/App.tsx +++ b/dashboard/packages/app/src/App.tsx @@ -118,11 +118,6 @@ const routes = ( ); const StateRefresh = ({ children }: { children: React.ReactNode }) => { - - - - - let { data: version } = useQuery(`${get_network()}_version`, async () => await fetchVersion().then((res) => res.json()) , { From c2948b850f0084e77644c58ef04a1f723caa6530 Mon Sep 17 00:00:00 2001 From: Pietro Date: Fri, 23 Aug 2024 14:22:59 +0200 Subject: [PATCH 40/40] POC 1: Add node list with rewards --- .../src/App.tsx | 7 +- .../{NodeChart.tsx => NodePage.tsx} | 5 +- .../src/components/SubnetChart.tsx | 76 ------------------- 3 files changed, 6 insertions(+), 82 deletions(-) rename rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/{NodeChart.tsx => NodePage.tsx} (94%) delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx index 941d0e826..561bc1363 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/App.tsx @@ -5,12 +5,10 @@ import Drawer from './components/Drawer'; import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom'; import { trustworthy_node_metrics } from '../../declarations/trustworthy-node-metrics/index.js'; import { NodeRewardsArgs, NodeRewardsResponse } from '../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did.js'; -import { DashboardNodeRewards } from './models/NodeMetrics'; import { NodeList } from './components/NodeList'; import Header from './components/Header'; import { dateToNanoseconds } from './utils/utils'; -import { SubnetChart } from './components/SubnetChart'; -import { NodeChart } from './components/NodeChart'; +import { NodeChart } from './components/NodePage'; // Theme configuration const darkTheme = createTheme({ @@ -111,7 +109,8 @@ const App: React.FC = () => { isLoading ? : } /> : + // TODO: Add subnet page + isLoading ? : } /> diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx similarity index 94% rename from rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx rename to rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx index 93f2d6329..ac97505e7 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeChart.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { ChartData, generateChartData } from '../utils/utils'; import { WidgetGauge, WidgetNumber } from './Widgets'; import { PeriodFilter } from './FilterBar'; -import { Box, Grid, Paper, Typography } from '@mui/material'; +import { Box, Divider, Grid, Paper, Typography } from '@mui/material'; import { useParams } from 'react-router-dom'; import DailyPerformanceChart from './DailyPerformanceChart'; import NodeInfo from './NodeInfo'; @@ -37,7 +37,7 @@ export const NodeChart: React.FC = ({ nodeRewards, periodFilter return

Node metrics not found

; } - const chartDailyData: ChartData[] = generateChartData(periodFilter, nodeMetrics.daily_node_metrics); + const chartDailyData: ChartData[] = generateChartData(periodFilter, nodeMetrics.daily_node_metrics, nodeMetrics.node_id); const failureRateAvg = `${Math.round(nodeMetrics.rewards_stats.failure_rate * 100)}%`; const rewardPercent = `${Math.round(nodeMetrics.rewards_percent * 100)}%`; @@ -49,6 +49,7 @@ export const NodeChart: React.FC = ({ nodeRewards, periodFilter {"Node Machine"} + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx deleted file mode 100644 index 2deceb0cc..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/SubnetChart.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useState } from 'react'; -import { Box, Paper, Typography } from '@mui/material'; -import { axisClasses, BarChart, StackOrderType } from '@mui/x-charts'; -import Divider from '@mui/material/Divider'; -import { useParams } from 'react-router-dom'; -import { generateChartData, getFormattedDates } from '../utils/utils'; -import RewardTable from './RewardTable'; -import { PeriodFilter } from './FilterBar'; -import { Root } from './NodeList'; -import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; - -export interface SubnetChartProps { - nodeRewards: NodeRewardsResponse[], - periodFilter: PeriodFilter - } - -export const SubnetChart: React.FC = ({ nodeRewards, periodFilter }) => { - const [stackOrder] = useState('ascending'); - const { subnet } = useParams(); - const subnetNodeMetrics = nodeRewards - .filter((nodeMetrics) => nodeMetrics.daily_node_metrics.some((daily) => daily.subnet_assigned.toText() === subnet)) - const chartData = nodeRewards - .filter((nodeMetrics) => nodeMetrics.daily_node_metrics.some(data => data.failure_rate >= 0.1)) - .map(nodeMetrics => { - return { - data: generateChartData(periodFilter, nodeMetrics.daily_node_metrics).map(daily => 3), - label: nodeMetrics.node_id.toText(), - } - }); - - console.info(chartData) - const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; - - return ( - - - - - Subnet: {subnet} - - - - - Daily Failure Rate (grater 10%) - `${value}%`, - label: 'Failure Rate', - min: 0, - max: 100, - }, - ]} - sx={{ - p: 2, - [`.${axisClasses.left} .${axisClasses.label}`]: { - transform: 'translateX(-25px)', - }, - }} - borderRadius={9} - series={series} - height={500} - /> - - - - - - - ); -};