From 8ac9e4ccd58bbcf4e55175880914106165c0ac24 Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 26 Aug 2024 17:30:08 +0200 Subject: [PATCH 1/5] Add node data page --- .../package-lock.json | 959 ++++++++++++++++-- .../package.json | 3 +- .../src/components/NodeDailyData.tsx | 31 + .../src/components/NodePage.tsx | 3 + 4 files changed, 914 insertions(+), 82 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx diff --git a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json index 8c4b8d47b..a39a27fcd 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/package-lock.json +++ b/rs/dre-canisters/trustworthy-node-metrics/package-lock.json @@ -1995,9 +1995,9 @@ "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==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2700,6 +2700,43 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@fast-csv/format": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", + "integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isboolean": "^3.0.3", + "lodash.isequal": "^4.5.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0" + } + }, + "node_modules/@fast-csv/format/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + }, + "node_modules/@fast-csv/parse": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz", + "integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==", + "dependencies": { + "@types/node": "^14.0.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.groupby": "^4.6.0", + "lodash.isfunction": "^3.0.9", + "lodash.isnil": "^4.0.0", + "lodash.isundefined": "^3.0.1", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/@fast-csv/parse/node_modules/@types/node": { + "version": "14.18.63", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", + "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==" + }, "node_modules/@floating-ui/core": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", @@ -2983,12 +3020,12 @@ } }, "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==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.4", + "@mui/utils": "^5.16.6", "prop-types": "^15.8.1" }, "engines": { @@ -3009,9 +3046,9 @@ } }, "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==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.11.0", @@ -3040,15 +3077,15 @@ } }, "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==", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.4", - "@mui/styled-engine": "^5.16.4", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.4", + "@mui/utils": "^5.16.6", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -3092,11 +3129,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", - "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", "dependencies": { "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", "@types/prop-types": "^15.7.12", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -3157,19 +3195,18 @@ } } }, - "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/@mui/x-data-grid": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.14.0.tgz", + "integrity": "sha512-ddVtvFXmENHADHzO0TGV2dzUQflexsXMbxEKMq3rBmgJ9QyeiZWBEwzgDps1CzqU5vi9QyDACCcPyoAuL6t3tQ==", "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", + "@babel/runtime": "^7.25.0", + "@mui/system": "^5.16.7", + "@mui/utils": "^5.16.6", + "@mui/x-internals": "7.14.0", "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" + "reselect": "^4.1.8" }, "engines": { "node": ">=14.0.0" @@ -3182,13 +3219,6 @@ "@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" }, @@ -3198,41 +3228,126 @@ }, "@emotion/styled": { "optional": true - }, - "date-fns": { - "optional": true - }, - "date-fns-jalali": { + } + } + }, + "node_modules/@mui/x-data-grid-generator": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-generator/-/x-data-grid-generator-7.14.0.tgz", + "integrity": "sha512-MN9+RVzBcTkGd260Xke8lViuerKuTkPvaohkCUrWsNy+8O/g6sAhk9UbgHnsGh5Qy6fnX3cChcmbcMOmBDDjlg==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/x-data-grid-premium": "7.14.0", + "chance": "^1.1.12", + "clsx": "^2.1.1", + "lru-cache": "^10.4.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/icons-material": "^5.4.1", + "@mui/material": "^5.15.14", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { "optional": true }, - "dayjs": { + "@emotion/styled": { "optional": true - }, - "luxon": { + } + } + }, + "node_modules/@mui/x-data-grid-generator/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/@mui/x-data-grid-premium": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-premium/-/x-data-grid-premium-7.14.0.tgz", + "integrity": "sha512-ZlfC3fmwR9lVUIKuDMZ4z4HcTi30kfLoZrfPX9KC2VyrYHDMyCuYLqgH9Bq/VMijjfOIwyQubWfGsTqIitkwMA==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/system": "^5.16.7", + "@mui/utils": "^5.16.6", + "@mui/x-data-grid": "7.14.0", + "@mui/x-data-grid-pro": "7.14.0", + "@mui/x-internals": "7.14.0", + "@mui/x-license": "7.14.0", + "@types/format-util": "^1.0.4", + "clsx": "^2.1.1", + "exceljs": "^4.4.0", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "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 }, - "moment": { + "@emotion/styled": { "optional": true - }, - "moment-hijri": { + } + } + }, + "node_modules/@mui/x-data-grid-pro": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-7.14.0.tgz", + "integrity": "sha512-pHJ+gjXdUcPOQTg4yXJsts9oLjEnA75sqqjfi/GQyg7MNKdTJkT9MgcQrT5BAUjCFf9H+tlPpBEmvSQA1jE2hg==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/system": "^5.16.7", + "@mui/utils": "^5.16.6", + "@mui/x-data-grid": "7.14.0", + "@mui/x-internals": "7.14.0", + "@mui/x-license": "7.14.0", + "@types/format-util": "^1.0.4", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "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 }, - "moment-jalaali": { + "@emotion/styled": { "optional": true } } }, - "node_modules/@mui/x-date-pickers-pro": { + "node_modules/@mui/x-date-pickers": { "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==", + "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", - "@mui/x-date-pickers": "7.11.0", - "@mui/x-license": "7.11.0", + "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" @@ -3240,6 +3355,10 @@ "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", @@ -3284,13 +3403,32 @@ } } }, + "node_modules/@mui/x-internals": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.14.0.tgz", + "integrity": "sha512-+qWIHLgt2vgH6bKmf7IwRvS86UbZRWKAdDY/yTQJaqzCzyesUvQhD+WRxe1kpdCK8UE061S9/Ju7hLkM4kjRNA==", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@mui/utils": "^5.16.6" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, "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==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@mui/x-license/-/x-license-7.14.0.tgz", + "integrity": "sha512-s7qAxUw2qXpOYKp5LivxkF+bx63Ia9wdDTBw9k6xrnAiyFv17BJw+2/pNlty5bGNCnVmlVj9HclmudWYH+vtog==", "dependencies": { - "@babel/runtime": "^7.24.8", - "@mui/utils": "^5.16.2" + "@babel/runtime": "^7.25.0", + "@mui/utils": "^5.16.6" }, "engines": { "node": ">=14.0.0" @@ -3723,6 +3861,11 @@ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" }, + "node_modules/@types/format-util": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/format-util/-/format-util-1.0.4.tgz", + "integrity": "sha512-xrCYOdHh5zA3LUrn6CvspYwlzSWxPso11Lx32WnAG6KvLCRecKZ/Rh21PLXUkzUFsQmrGcx/traJAFjR6dVS5Q==" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -4166,6 +4309,75 @@ "node": ">= 8" } }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -4351,6 +4563,11 @@ "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -4470,8 +4687,7 @@ "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 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-arraybuffer": { "version": "0.2.0", @@ -4500,6 +4716,14 @@ } ] }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -4508,6 +4732,18 @@ "node": "*" } }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -4520,6 +4756,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + }, "node_modules/borc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/borc/-/borc-2.1.2.tgz", @@ -4541,7 +4792,6 @@ "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" @@ -4614,6 +4864,30 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", + "engines": { + "node": ">=0.2.0" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -4671,6 +4945,17 @@ } ] }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4684,6 +4969,11 @@ "node": ">=4" } }, + "node_modules/chance": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/chance/-/chance-1.1.12.tgz", + "integrity": "sha512-vVBIGQVnwtUG+SYe0ge+3MvF78cvSpuCOEUJr7sVEk2vSBuMW6OXNJjSzdtzrlxNUEaoqH2GBd5Y/+18BEB01Q==" + }, "node_modules/chart.js": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", @@ -4751,11 +5041,24 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "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 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", @@ -4782,6 +5085,11 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", @@ -4797,6 +5105,29 @@ "node": ">=10" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.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", @@ -5014,6 +5345,11 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -5174,6 +5510,46 @@ "url": "https://dotenvx.com" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", @@ -5186,6 +5562,14 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -5981,6 +6365,37 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, + "node_modules/exceljs": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz", + "integrity": "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==", + "dependencies": { + "archiver": "^5.0.0", + "dayjs": "^1.8.34", + "fast-csv": "^4.3.1", + "jszip": "^3.10.1", + "readable-stream": "^3.6.0", + "saxes": "^5.0.1", + "tmp": "^0.2.0", + "unzipper": "^0.10.11", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/fast-csv": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz", + "integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==", + "dependencies": { + "@fast-csv/format": "4.3.5", + "@fast-csv/parse": "4.3.6" + }, + "engines": { + "node": ">=10.0.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", @@ -6108,12 +6523,15 @@ "is-callable": "^1.1.3" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "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, - "peer": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -6129,6 +6547,33 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6214,8 +6659,6 @@ "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", @@ -6430,6 +6873,11 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/immutable": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", @@ -6465,8 +6913,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": { "once": "^1.3.0", "wrappy": "1" @@ -7004,6 +7450,49 @@ "node": ">=4.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/katex": { "version": "0.16.11", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", @@ -7054,6 +7543,49 @@ "node": ">=0.10" } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7067,11 +7599,24 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "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/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7098,12 +7643,77 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + }, + "node_modules/lodash.groupby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", + "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + }, + "node_modules/lodash.isnil": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz", + "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==" + }, "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/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7155,7 +7765,6 @@ "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" }, @@ -7167,11 +7776,21 @@ "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/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7292,7 +7911,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -7427,8 +8045,6 @@ "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" } @@ -7480,6 +8096,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7521,8 +8142,6 @@ "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" } @@ -7612,6 +8231,11 @@ "node": ">= 0.8.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -7786,6 +8410,33 @@ "node": ">= 6" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/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==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7942,6 +8593,11 @@ "jsesc": "bin/jsesc" } }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -8108,6 +8764,17 @@ "node": ">=14.0.0" } }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -8157,6 +8824,11 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8437,6 +9109,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8448,6 +9135,14 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "engines": { + "node": ">=14.14" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -8468,6 +9163,14 @@ "node": ">=8.0" } }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", + "engines": { + "node": "*" + } + }, "node_modules/trustworthy-node-metrics-frontend": { "resolved": "src/trustworthy-node-metrics-frontend", "link": true @@ -8994,6 +9697,55 @@ "node": ">=4" } }, + "node_modules/unzipper": { + "version": "0.10.14", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", + "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/unzipper/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", @@ -9038,6 +9790,14 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "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", @@ -9234,9 +9994,12 @@ "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 + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "node_modules/yallist": { "version": "3.1.1", @@ -9272,6 +10035,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, "src/trustworthy-node-metrics-frontend": { "version": "0.0.0", "dependencies": { @@ -9285,8 +10081,9 @@ "@mui/material": "^5.16.4", "@mui/types": "^7.2.15", "@mui/x-charts": "^7.11.0", + "@mui/x-data-grid": "^7.14.0", + "@mui/x-data-grid-generator": "^7.14.0", "@mui/x-date-pickers": "^7.11.0", - "@mui/x-date-pickers-pro": "^7.11.0", "date-fns": "^2.30.0", "katex": "^0.16.11", "next": "^14.2.5", 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 b5f9d087a..68941157b 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 @@ -27,8 +27,9 @@ "@mui/material": "^5.16.4", "@mui/types": "^7.2.15", "@mui/x-charts": "^7.11.0", + "@mui/x-data-grid": "^7.14.0", + "@mui/x-data-grid-generator": "^7.14.0", "@mui/x-date-pickers": "^7.11.0", - "@mui/x-date-pickers-pro": "^7.11.0", "date-fns": "^2.30.0", "katex": "^0.16.11", "next": "^14.2.5", diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx new file mode 100644 index 000000000..7bf5dad27 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { DataGrid, GridToolbarContainer, GridToolbarExport } from '@mui/x-data-grid'; +import { useDemoData } from '@mui/x-data-grid-generator'; + +function CustomToolbar() { + return ( + + + + ); +} + +export default function ExportCustomToolbar() { + const { data, loading } = useDemoData({ + dataSet: 'Commodity', + rowLength: 4, + maxColumns: 6, + }); + + return ( +
+ +
+ ); +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx index 0735b7b89..aff8c5cd7 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx @@ -73,6 +73,9 @@ export const NodeChart: React.FC = ({ nodeRewards, periodFilter + + + From a0ffb47146f5dc1560d5a4314ba56b4c998aa83d Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 26 Aug 2024 21:43:22 +0200 Subject: [PATCH 2/5] Add node provider page --- .../src/App.tsx | 17 +++-- .../src/components/Drawer.tsx | 6 +- .../src/components/NodePage.tsx | 7 +- .../src/components/NodeProviderPage.tsx | 71 +++++++++++++++++++ 4 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.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 55a30d407..cbd1f6a53 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 @@ -8,7 +8,8 @@ import { NodeRewardsArgs, NodeRewardsResponse } from '../../declarations/trustwo import { NodeList } from './components/NodeList'; import Header from './components/Header'; import { dateToNanoseconds } from './utils/utils'; -import { NodeChart } from './components/NodePage'; +import { NodePage } from './components/NodePage'; +import { NodeProviderPage } from './components/NodeProviderPage'; // Theme configuration const darkTheme = createTheme({ @@ -51,7 +52,7 @@ const App: React.FC = () => { const [periodFilter, setPeriodFilter] = useState({ dateStart, dateEnd }); const [nodeRewards, setNodeRewards] = useState([]); const [subnets, setSubnets] = useState>(new Set()); - const [nodeProviders, setNodeProviders] = useState>(new Set()); + const [providers, setProviders] = useState>(new Set()); const [isLoading, setIsLoading] = useState(true); const [drawerOpen, setDrawerOpen] = useState(false); const theme = useTheme(); @@ -69,9 +70,11 @@ const App: React.FC = () => { 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 providers = new Set(sortedNodeRewards.flatMap(node => node.node_provider_id.toText())); setNodeRewards(sortedNodeRewards); setSubnets(subnets); + setProviders(providers); } catch (error) { console.error("Error fetching node:", error); } finally { @@ -84,12 +87,12 @@ const App: React.FC = () => { const drawerProps = useMemo(() => ({ subnets, - nodeProviders, + providers, drawerWidth, temporary: isSmallScreen, drawerOpen, onClosed: () => setDrawerOpen(false) - }), [subnets, nodeProviders, drawerWidth, isSmallScreen, drawerOpen]); + }), [subnets, providers, drawerWidth, isSmallScreen, drawerOpen]); return ( @@ -107,12 +110,16 @@ const App: React.FC = () => { isLoading ? : } /> : + isLoading ? : } /> : } /> + : + } /> 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 679bd2e2e..2a8b5f2b0 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 @@ -17,14 +17,14 @@ import { ExpandLess, ExpandMore } from '@mui/icons-material'; interface DrawerProps { subnets: Set; - nodeProviders: Set; + providers: Set; drawerWidth: number; temporary: boolean; drawerOpen: boolean; onClosed: () => void; } -const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth, temporary, drawerOpen, onClosed }) => { +const Drawer: React.FC = ({ subnets, providers, drawerWidth, temporary, drawerOpen, onClosed }) => { const [isSubnetsOpen, setIsSubnetsOpen] = React.useState(false); const [isNodeProvidersOpen, setIsNodeProvidersOpen] = React.useState(false); @@ -85,7 +85,7 @@ const Drawer: React.FC = ({ subnets, nodeProviders, drawerWidth, te {renderCollapsibleList("Subnets", subnets, isSubnetsOpen, setIsSubnetsOpen, "subnets")} - {renderCollapsibleList("Node Providers", nodeProviders, isNodeProvidersOpen, setIsNodeProvidersOpen, "node-providers")} + {renderCollapsibleList("Node Providers", providers, isNodeProvidersOpen, setIsNodeProvidersOpen, "providers")} ); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx index aff8c5cd7..30ddc5a14 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx @@ -9,8 +9,9 @@ import NodeInfo from './NodeInfo'; import { paperStyle, boxStyleWidget } from '../Styles'; import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; import RewardsInfo, { LinearReductionChart } from './RewardsInfo'; +import ExportCustomToolbar from './NodeDailyData'; -export interface NodeChartProps { +export interface NodePageProps { nodeRewards: NodeRewardsResponse[]; periodFilter: PeriodFilter; } @@ -29,7 +30,7 @@ const NodePerformanceStats: React.FC<{ rewardsReduction: string }> = ({ rewardsR ); -export const NodeChart: React.FC = ({ nodeRewards, periodFilter }) => { +export const NodePage: React.FC = ({ nodeRewards, periodFilter }) => { const { node } = useParams(); const nodeMetrics = nodeRewards.find((metrics) => metrics.node_id.toText() === node); @@ -82,4 +83,4 @@ export const NodeChart: React.FC = ({ nodeRewards, periodFilter ); }; -export default NodeChart; +export default NodePage; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx new file mode 100644 index 000000000..01e9c4e90 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx @@ -0,0 +1,71 @@ +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 { PeriodFilter } from './FilterBar'; +import { Root } from './NodeList'; +import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; + +export interface NodeProviderPageProps { + nodeRewards: NodeRewardsResponse[], + periodFilter: PeriodFilter + } + +export const NodeProviderPage: React.FC = ({ nodeRewards, periodFilter }) => { + const [stackOrder] = useState('ascending'); + const { provider } = useParams(); + const providerNodeMetrics = nodeRewards + .filter((nodeMetrics) => nodeMetrics.node_provider_id.toText() === provider) + const chartData = providerNodeMetrics + .map(nodeMetrics => { + return { + data: generateChartData(periodFilter, nodeMetrics.daily_node_metrics), + label: provider, + } + }); + + console.info(chartData) + const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; + + return ( + + + + + Node Provider: {provider} + + + + + 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} + /> + + + + ); +}; From a0f78c6f87c0d010f192599a55e64b9471295395 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 27 Aug 2024 15:08:23 +0200 Subject: [PATCH 3/5] Add export functionality --- .../src/components/ExportTable.tsx | 29 +++++ .../src/components/NodeDailyData.tsx | 45 ------- .../src/components/NodeInfo.tsx | 21 ++-- .../src/components/NodePage.tsx | 39 ++++-- .../src/components/NodeProviderPage.tsx | 114 ++++++++++++------ .../src/components/RewardsInfo.tsx | 55 +++++++-- .../src/utils/utils.tsx | 18 ++- trusted-neurons-alerts/governance.py | 3 +- 8 files changed, 198 insertions(+), 126 deletions(-) create mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ExportTable.tsx delete mode 100644 rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ExportTable.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ExportTable.tsx new file mode 100644 index 000000000..7edb5db10 --- /dev/null +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/ExportTable.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import { DataGrid, GridColDef, GridRowsProp, GridToolbarContainer, GridToolbarExport } from '@mui/x-data-grid'; + +function CustomToolbar() { + return ( + + + + ); +} + +interface ExportCustomToolbarProps { + colDef: GridColDef[]; + rows: GridRowsProp; +} + +export const ExportTable: React.FC = ({ colDef, rows }) => { + return ( +
+ +
+ ); +} diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx deleted file mode 100644 index 2b33d8338..000000000 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeDailyData.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import * as React from 'react'; -import { DataGrid, GridColDef, GridRowsProp, GridToolbarContainer, GridToolbarExport } from '@mui/x-data-grid'; -import { ChartData } from '../utils/utils'; - -function CustomToolbar() { - return ( - - - - ); -} - -interface ExportCustomToolbarProps { - chartDailyData: ChartData[]; -} - -export const ExportCustomToolbar: React.FC = ({ chartDailyData }) => { - const rows: GridRowsProp = chartDailyData.map((dailyData, index) => { - return { - id: index + 1, - col1: dailyData.date.toLocaleDateString('en-GB'), - col2: dailyData.dailyNodeMetrics?.num_blocks_proposed, - col3: dailyData.dailyNodeMetrics?.num_blocks_failed, - col4: dailyData.dailyNodeMetrics?.subnet_assigned, - }; - }); - - const columns: GridColDef[] = [ - { field: 'col1', headerName: 'Date', width: 200 }, - { field: 'col2', headerName: 'Blocks Proposed', width: 150 }, - { field: 'col3', headerName: 'Blocks Failed', width: 150 }, - { field: 'col4', headerName: 'Subnet Assigned', width: 550 }, - ]; - return ( -
- -
- ); -} 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 index 2311b46a5..db8648ca5 100644 --- 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 @@ -1,29 +1,22 @@ import React from 'react'; import Typography from '@mui/material/Typography'; -interface NodeInfoProps { - nodeId: string; - nodeProviderId: string; +interface InfoFormatterProps { + name: string; + value: string; } -const NodeInfo: React.FC = ({ nodeId, nodeProviderId }) => { +const InfoFormatter: React.FC = ({ name, value }) => { return (
- {"Node ID"} + {name} - {nodeId} - - - - {"Node Provider ID"} - - - {nodeProviderId} + {value}
); }; -export default NodeInfo; +export default InfoFormatter; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx index 3fbf561f9..58bfc2d71 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx @@ -1,16 +1,16 @@ import React from 'react'; -import { ChartData, generateChartData } from '../utils/utils'; +import { ChartData, formatDateToUTC, generateChartData } from '../utils/utils'; import { WidgetGauge, WidgetNumber } from './Widgets'; import { PeriodFilter } from './FilterBar'; import { Box, Divider, Grid, Paper, Typography } from '@mui/material'; import { useParams } from 'react-router-dom'; import DailyPerformanceChart from './DailyPerformanceChart'; -import NodeInfo from './NodeInfo'; import { paperStyle, boxStyleWidget } from '../Styles'; import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; -import RewardsInfo, { LinearReductionChart } from './RewardsInfo'; -import ExportCustomToolbar from './NodeDailyData'; -import { ExportCustomToolbar } from './NodeDailyData'; +import RewardsInfo from './RewardsInfo'; +import { ExportTable } from './ExportTable'; +import InfoFormatter from './NodeInfo'; +import { GridColDef, GridRowsProp } from '@mui/x-data-grid'; export interface NodePageProps { nodeRewards: NodeRewardsResponse[]; @@ -44,6 +44,27 @@ export const NodePage: React.FC = ({ nodeRewards, periodFilter }) const rewardsPercent = Math.round(nodeMetrics.rewards_percent * 100); const rewardsReduction = 100 - rewardsPercent; + let index = 0; + const rows: GridRowsProp = nodeMetrics.daily_node_metrics.map((data) => { + index = index + 1; + return { + id: index, + col1: new Date(Number(data.ts) / 1000000), + col2: data.num_blocks_proposed, + col3: data.num_blocks_failed, + col4: data.failure_rate, + col5: data.subnet_assigned, + }; + }); + + const colDef: GridColDef[] = [ + { field: 'col1', headerName: 'Date (UTC)', width: 200, valueFormatter: (value: Date) => formatDateToUTC(value)}, + { field: 'col2', headerName: 'Blocks Proposed', width: 150 }, + { field: 'col3', headerName: 'Blocks Failed', width: 150 }, + { field: 'col4', headerName: 'Daily Failure Rate', width: 350 , valueFormatter: (value: number) => `${value * 100}%`,}, + { field: 'col5', headerName: 'Subnet Assigned', width: 550 }, + ]; + return ( @@ -55,7 +76,8 @@ export const NodePage: React.FC = ({ nodeRewards, periodFilter }) - + + @@ -73,10 +95,7 @@ export const NodePage: React.FC = ({ nodeRewards, periodFilter }) - - - - + diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx index 01e9c4e90..052981da0 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx @@ -1,12 +1,16 @@ import React, { useState } from 'react'; -import { Box, Paper, Typography } from '@mui/material'; +import { Box, Grid, 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 { formatDateToUTC, generateChartData, getFormattedDates } from '../utils/utils'; import { PeriodFilter } from './FilterBar'; import { Root } from './NodeList'; import { NodeRewardsResponse } from '../../../declarations/trustworthy-node-metrics/trustworthy-node-metrics.did'; +import { paperStyle } from '../Styles'; +import InfoFormatter from './NodeInfo'; +import { ExportTable } from './ExportTable'; +import { GridColDef, GridRowsProp } from '@mui/x-data-grid'; export interface NodeProviderPageProps { nodeRewards: NodeRewardsResponse[], @@ -14,58 +18,88 @@ export interface NodeProviderPageProps { } export const NodeProviderPage: React.FC = ({ nodeRewards, periodFilter }) => { - const [stackOrder] = useState('ascending'); const { provider } = useParams(); const providerNodeMetrics = nodeRewards .filter((nodeMetrics) => nodeMetrics.node_provider_id.toText() === provider) - const chartData = providerNodeMetrics - .map(nodeMetrics => { + const highFailureRateChart = providerNodeMetrics + .filter(nodeMetrics => nodeMetrics.rewards_stats.rewards_reduction > 0) + .flatMap(nodeMetrics => { + const chartData = generateChartData(periodFilter, nodeMetrics.daily_node_metrics); return { - data: generateChartData(periodFilter, nodeMetrics.daily_node_metrics), - label: provider, - } + data: chartData.map(data => data.dailyNodeMetrics? data.dailyNodeMetrics.failure_rate * 100: null), + label: nodeMetrics.node_id.toText(), + stack: 'total' + } }); - console.info(chartData) - const series = [{ ...chartData[0], stackOrder }, ...chartData.slice(1)]; + let index = 0; + const rows: GridRowsProp = providerNodeMetrics.flatMap((nodeRewards) => { + return nodeRewards.daily_node_metrics.map((data) => { + index = index + 1; + return { + id: index, + col1: new Date(Number(data.ts) / 1000000), + col2: nodeRewards.node_id, + col3: data.num_blocks_proposed, + col4: data.num_blocks_failed, + col5: data.failure_rate, + col6: data.subnet_assigned, + }; + }) + }); + + const colDef: GridColDef[] = [ + { field: 'col1', headerName: 'Date (UTC)', width: 200, valueFormatter: (value: Date) => formatDateToUTC(value)}, + { field: 'col2', headerName: 'Node ID', width: 550 }, + { field: 'col3', headerName: 'Blocks Proposed', width: 150 }, + { field: 'col4', headerName: 'Blocks Failed', width: 150 }, + { field: 'col5', headerName: 'Daily Failure Rate', width: 350 , valueFormatter: (value: number) => `${value * 100}%`,}, + { field: 'col6', headerName: 'Subnet Assigned', width: 550 }, + ]; return ( - - - - - Node Provider: {provider} - - - - - Daily Failure Rate (grater 10%) - + + + + + {"Node Provider"} + + + + + + + + + Daily Failure Rate + + + For nodes with rewards reduction + + + + `${value}%`, - label: 'Failure Rate', - min: 0, - max: 100, - }, - ]} - sx={{ - p: 2, - [`.${axisClasses.left} .${axisClasses.label}`]: { - transform: 'translateX(-25px)', - }, - }} + yAxis={[{ + valueFormatter: (value: number) => `${value}%`, + }]} + leftAxis={null} borderRadius={9} - series={series} - height={500} + series={highFailureRateChart} + height={300} /> - - - + + + + + + + ); }; diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardsInfo.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardsInfo.tsx index 76912919a..8086b3bcd 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardsInfo.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/RewardsInfo.tsx @@ -7,20 +7,23 @@ import { axisClasses, ChartsReferenceLine, LineChart } from '@mui/x-charts'; const NodeRewardExplanation: React.FC<{ failureRate: number; rewardReduction: number }> = ({ failureRate, rewardReduction }) => { return ( + {/* Title Section */} How are rewards computed? - + + {/* Node Unassigned Section */} + Node Unassigned: When a node is not assigned to any subnet, it automatically receives the full reward (100%). No further calculations are needed. - - {/* Assigned Node */} + + {/* Node Assigned Section */} Node Assigned: @@ -42,9 +45,8 @@ const NodeRewardExplanation: React.FC<{ failureRate: number; rewardReduction: nu - - + {/* Failure Rate Calculation */} @@ -61,9 +63,12 @@ const NodeRewardExplanation: React.FC<{ failureRate: number; rewardReduction: nu + - {/* Apply Linear Reduction Function */} - + {/* Reward Reduction Section */} + + {/* Linear Reduction Function */} + Apply Linear Reduction Function: @@ -71,19 +76,47 @@ const NodeRewardExplanation: React.FC<{ failureRate: number; rewardReduction: nu Based on the failure rate, we apply a linear reduction function to determine how much the failure rate reduces the node's rewards. + + {/* Specific Failure Rate Conditions */} + + + + Failure Rates Below 10%: For failure rates ≤ 10%, there is no reduction in rewards. The rewards reduction is 0%, meaning for performance below this threshold, rewards remain unaffected. + + + + + Failure Rates Above 70%: Once the failure rate exceeds 70%, the rewards reduction reaches its maximum of 100%. Any failure rate beyond this threshold results in a complete loss of rewards. + + + + - The final reward percentage is computed by subtracting the rewards reduction from 100%. + The final reward percentage for the assigned period is computed by subtracting the rewards reduction from 100%. + + + + {/* Total Rewards Calculation Placeholder */} + + + Compute total rewards: + + + Work in progress... - - + + {/* Reward Reduction Chart */} + + ); }; + export default NodeRewardExplanation; export const LinearReductionChart: React.FC<{ failureRate: number; rewardReduction: number }> = ({ failureRate, rewardReduction }) => { @@ -107,7 +140,7 @@ export const LinearReductionChart: React.FC<{ failureRate: number; rewardReducti Linear Rewards Reduction { return dates; }; - 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; - }; +export const formatDateToUTC = (date: Date): string => { + const day = String(date.getUTCDate()).padStart(2, '0'); + const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // Months are zero-indexed + const year = date.getUTCFullYear(); + return `${day}-${month}-${year}`; + }; + +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; + }; + diff --git a/trusted-neurons-alerts/governance.py b/trusted-neurons-alerts/governance.py index 24e376624..a8d94e9f6 100644 --- a/trusted-neurons-alerts/governance.py +++ b/trusted-neurons-alerts/governance.py @@ -51,6 +51,7 @@ def _get_recent_ballots(self): governance_canister = Canister(agent=self.agent, canister_id=self.principal, candid=open(governance_did, encoding="utf8").read()) response = governance_canister.get_neuron_info(DFINITY_NEURON_ID) + print(response) recent_ballots = response[0].get('Ok', {}).get('recent_ballots', []) return recent_ballots @@ -72,7 +73,7 @@ def has_dfinity_voted(self, proposal_id: int) -> bool: def main(): canister = GovernanceCanister() - print(canister.has_dfinity_voted(0)) + print(canister._get_recent_ballots()) if __name__ == "__main__": From 9957eedffac44547c77c614766f6f1eb3c095b89 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 27 Aug 2024 15:10:04 +0200 Subject: [PATCH 4/5] Add Node Provide Page --- trusted-neurons-alerts/governance.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/trusted-neurons-alerts/governance.py b/trusted-neurons-alerts/governance.py index a8d94e9f6..24e376624 100644 --- a/trusted-neurons-alerts/governance.py +++ b/trusted-neurons-alerts/governance.py @@ -51,7 +51,6 @@ def _get_recent_ballots(self): governance_canister = Canister(agent=self.agent, canister_id=self.principal, candid=open(governance_did, encoding="utf8").read()) response = governance_canister.get_neuron_info(DFINITY_NEURON_ID) - print(response) recent_ballots = response[0].get('Ok', {}).get('recent_ballots', []) return recent_ballots @@ -73,7 +72,7 @@ def has_dfinity_voted(self, proposal_id: int) -> bool: def main(): canister = GovernanceCanister() - print(canister._get_recent_ballots()) + print(canister.has_dfinity_voted(0)) if __name__ == "__main__": From cbdf2140a63ed012cfd937eb80a96d5091066332 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 27 Aug 2024 18:19:21 +0200 Subject: [PATCH 5/5] Fix export table sorting --- .../src/components/NodePage.tsx | 12 +++++------- .../src/components/NodeProviderPage.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx index 58bfc2d71..30a7cabf9 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodePage.tsx @@ -44,16 +44,14 @@ export const NodePage: React.FC = ({ nodeRewards, periodFilter }) const rewardsPercent = Math.round(nodeMetrics.rewards_percent * 100); const rewardsReduction = 100 - rewardsPercent; - let index = 0; - const rows: GridRowsProp = nodeMetrics.daily_node_metrics.map((data) => { - index = index + 1; + const rows: GridRowsProp = nodeMetrics.daily_node_metrics.map((data, index) => { return { - id: index, + id: index + 1, col1: new Date(Number(data.ts) / 1000000), - col2: data.num_blocks_proposed, - col3: data.num_blocks_failed, + col2: Number(data.num_blocks_proposed), + col3: Number(data.num_blocks_failed), col4: data.failure_rate, - col5: data.subnet_assigned, + col5: data.subnet_assigned.toText(), }; }); diff --git a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx index 052981da0..dc1b7e84a 100644 --- a/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx +++ b/rs/dre-canisters/trustworthy-node-metrics/src/trustworthy-node-metrics-frontend/src/components/NodeProviderPage.tsx @@ -39,11 +39,11 @@ export const NodeProviderPage: React.FC = ({ nodeRewards, return { id: index, col1: new Date(Number(data.ts) / 1000000), - col2: nodeRewards.node_id, - col3: data.num_blocks_proposed, - col4: data.num_blocks_failed, + col2: nodeRewards.node_id.toText(), + col3: Number(data.num_blocks_proposed), + col4: Number(data.num_blocks_failed), col5: data.failure_rate, - col6: data.subnet_assigned, + col6: data.subnet_assigned.toText(), }; }) });