From 94c9ee659cc3e8fa41c6e42d658d338dafbd094a Mon Sep 17 00:00:00 2001 From: Hatim Dinia <33469289+hdinia@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:54:22 +0200 Subject: [PATCH 01/17] chore(deps): add `GlideDataGrid` package (#2073) --- webapp/package-lock.json | 845 +++++++++++++++++++++++++++++++++++---- webapp/package.json | 1 + 2 files changed, 772 insertions(+), 74 deletions(-) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index c7e11dc01b..04eacca025 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", + "@glideapps/glide-data-grid": "^6.0.3", "@handsontable/react": "14.1.0", "@mui/icons-material": "5.14.11", "@mui/lab": "5.0.0-alpha.146", @@ -115,117 +116,270 @@ "node": ">=0.10.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==", + "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.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "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.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/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==", + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "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==" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dependencies": { - "color-convert": "^1.9.0" + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/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/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/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/@babel/helper-compilation-targets/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==", "dependencies": { - "color-name": "1.1.3" + "yallist": "^3.0.2" } }, - "node_modules/@babel/code-frame/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/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/@babel/code-frame/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/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "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": ">=0.8.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/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/@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": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/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==", + "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": { - "has-flag": "^3.0.0" + "@babel/types": "^7.24.7" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "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==", + "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.22.15" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -295,6 +449,71 @@ "node": ">=4" } }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.23.8", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", @@ -318,13 +537,54 @@ "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.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/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/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -960,6 +1220,23 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, + "node_modules/@glideapps/glide-data-grid": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@glideapps/glide-data-grid/-/glide-data-grid-6.0.3.tgz", + "integrity": "sha512-YXKggiNOaEemf0jP0jORq2EQKz+zXms+6mGzZc+q0mLMjmgzzoGLOQC1uYcynXSj1R61bd27JcPFsoH+Gj37Vg==", + "dependencies": { + "@linaria/react": "^4.5.3", + "canvas-hypertxt": "^1.0.3", + "react-number-format": "^5.0.0" + }, + "peerDependencies": { + "lodash": "^4.17.19", + "marked": "^4.0.10", + "react": "^16.12.0 || 17.x || 18.x", + "react-dom": "^16.12.0 || 17.x || 18.x", + "react-responsive-carousel": "^3.2.7" + } + }, "node_modules/@handsontable/pikaday": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@handsontable/pikaday/-/pikaday-1.0.0.tgz", @@ -1014,11 +1291,173 @@ "react": "*" } }, + "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.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, + "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/@linaria/core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@linaria/core/-/core-4.5.4.tgz", + "integrity": "sha512-vMs/5iU0stxjfbBCxobIgY+wSQx4G8ukNwrhjPVD+6bF9QrTwi5rl0mKaCMxaGMjnfsLRiiM3i+hnWLIEYLdSg==", + "dependencies": { + "@linaria/logger": "^4.5.0", + "@linaria/tags": "^4.5.4", + "@linaria/utils": "^4.5.3" + }, + "engines": { + "node": "^12.16.0 || >=13.7.0" + } + }, + "node_modules/@linaria/logger": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@linaria/logger/-/logger-4.5.0.tgz", + "integrity": "sha512-XdQLk242Cpcsc9a3Cz1ktOE5ysTo2TpxdeFQEPwMm8Z/+F/S6ZxBDdHYJL09srXWz3hkJr3oS2FPuMZNH1HIxw==", + "dependencies": { + "debug": "^4.1.1", + "picocolors": "^1.0.0" + }, + "engines": { + "node": "^12.16.0 || >=13.7.0" + } + }, + "node_modules/@linaria/react": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@linaria/react/-/react-4.5.4.tgz", + "integrity": "sha512-/dhCVCsfdGPfQCPV0q5yy+DDlFXepvfXrw/os2fC+Xo1v9J/9gyiaBBWHzcumauvNNFj8aN6vRkj89fMujPHew==", + "dependencies": { + "@emotion/is-prop-valid": "^1.2.0", + "@linaria/core": "^4.5.4", + "@linaria/tags": "^4.5.4", + "@linaria/utils": "^4.5.3", + "minimatch": "^9.0.3", + "react-html-attributes": "^1.4.6", + "ts-invariant": "^0.10.3" + }, + "engines": { + "node": "^12.16.0 || >=13.7.0" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/@linaria/react/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/@linaria/react/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@linaria/tags": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@linaria/tags/-/tags-4.5.4.tgz", + "integrity": "sha512-HPxLB6HlJWLi6o8+8lTLegOmDnbMbuzEE+zzunaPZEGSoIIYx8HAv5VbY/sG/zNyxDElk6laiAwEVWN8h5/zxg==", + "dependencies": { + "@babel/generator": "^7.22.9", + "@linaria/logger": "^4.5.0", + "@linaria/utils": "^4.5.3" + }, + "engines": { + "node": "^12.16.0 || >=13.7.0" + } + }, + "node_modules/@linaria/utils": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@linaria/utils/-/utils-4.5.3.tgz", + "integrity": "sha512-tSpxA3Zn0DKJ2n/YBnYAgiDY+MNvkmzAHrD8R9PKrpGaZ+wz1jQEmE1vGn1cqh8dJyWK0NzPAA8sf1cqa+RmAg==", + "dependencies": { + "@babel/core": "^7.22.9", + "@babel/generator": "^7.22.9", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.8", + "@babel/types": "^7.22.5", + "@linaria/logger": "^4.5.0", + "babel-merge": "^3.0.0", + "find-up": "^5.0.0", + "minimatch": "^9.0.3" + }, + "engines": { + "node": "^12.16.0 || >=13.7.0" + } + }, + "node_modules/@linaria/utils/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/@linaria/utils/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@mapbox/geojson-rewind": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", @@ -4187,6 +4626,27 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/babel-merge": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/babel-merge/-/babel-merge-3.0.0.tgz", + "integrity": "sha512-eBOBtHnzt9xvnjpYNI5HmaPp/b2vMveE5XggzqHnQeHJ8mFIBrBv6WZEVIj5jJ2uwTItkqKo9gWzEEcBxEq0yw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dependencies": { + "deepmerge": "^2.2.1", + "object.omit": "^3.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-merge/node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -4282,6 +4742,37 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "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.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "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", @@ -4344,6 +4835,25 @@ "node": ">=6" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "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/canvas-fit": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/canvas-fit/-/canvas-fit-1.5.0.tgz", @@ -4352,6 +4862,11 @@ "element-size": "^1.1.1" } }, + "node_modules/canvas-hypertxt": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/canvas-hypertxt/-/canvas-hypertxt-1.0.3.tgz", + "integrity": "sha512-+VsMpRr64jYgKq2IeFUNel3vCZH/IzS+iXSHxmUV3IUH5dXlC9xHz4AwtPZisDxZ5MWcuK0V+TXgPKFPiZnxzg==" + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5282,6 +5797,11 @@ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" }, + "node_modules/electron-to-chromium": { + "version": "1.4.805", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.805.tgz", + "integrity": "sha512-8W4UJwX/w9T0QSzINJckTKG6CYpAUTqsaWcWIsdud3I1FYJcMgW9QqT1/4CBff/pP/TihWh13OmiyY8neto6vw==" + }, "node_modules/element-size": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/element-size/-/element-size-1.1.1.tgz", @@ -5516,6 +6036,14 @@ "@esbuild/win32-x64": "0.19.12" } }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "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", @@ -6120,7 +6648,6 @@ "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" @@ -6364,6 +6891,14 @@ "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==", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/geojson-vt": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", @@ -6943,6 +7478,11 @@ "resolved": "https://registry.npmjs.org/hsluv/-/hsluv-0.0.3.tgz", "integrity": "sha512-08iL2VyCRbkQKBySkSh6m8zMUa3sADAxGVWs3Z1aPcUkTJeK0ETG4Fc27tEmQBGUAXZjIsXOZqBvacuVNSC/fQ==" }, + "node_modules/html-element-attributes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-element-attributes/-/html-element-attributes-1.3.1.tgz", + "integrity": "sha512-UrRKgp5sQmRnDy4TEwAUsu14XBUlzKB8U3hjIYDjcZ3Hbp86Jtftzxfgrv6E/ii/h78tsaZwAnAE8HwnHr0dPA==" + }, "node_modules/html-parse-stringify": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", @@ -7324,6 +7864,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -7637,6 +8199,14 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -7701,6 +8271,17 @@ "node": ">=12.0.0" } }, + "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-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -7745,6 +8326,17 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsoneditor": { "version": "9.10.4", "resolved": "https://registry.npmjs.org/jsoneditor/-/jsoneditor-9.10.4.tgz", @@ -7852,7 +8444,6 @@ "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" }, @@ -7977,6 +8568,18 @@ "node": ">=6.4.0" } }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/material-colors": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", @@ -8339,6 +8942,11 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, "node_modules/normalize-svg-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-0.1.0.tgz", @@ -8481,6 +9089,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.omit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz", + "integrity": "sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==", + "dependencies": { + "is-extendable": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object.values": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", @@ -8550,7 +9169,6 @@ "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" }, @@ -8565,7 +9183,6 @@ "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" }, @@ -8704,7 +9321,6 @@ "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" } @@ -8761,10 +9377,9 @@ "integrity": "sha512-ESj2+eBxhGrcA1azgHs7lARG5+5iLakc/6nlfbpjcLl00HuuUOIuORhYXN4D1HfvMSKuVtFQjAlnwi1JHEeDIw==" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "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", @@ -9333,6 +9948,18 @@ "react": ">= 16.8 || 18.0.0" } }, + "node_modules/react-easy-swipe": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz", + "integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==", + "peer": true, + "dependencies": { + "prop-types": "^15.5.8" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/react-hook-form": { "version": "7.47.0", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.47.0.tgz", @@ -9348,6 +9975,14 @@ "react": "^16.8.0 || ^17 || ^18" } }, + "node_modules/react-html-attributes": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/react-html-attributes/-/react-html-attributes-1.4.6.tgz", + "integrity": "sha512-uS3MmThNKFH2EZUQQw4k5pIcU7XIr208UE5dktrj/GOH1CMagqxDl4DCLpt3o2l9x+IB5nVYBeN3Cr4IutBXAg==", + "dependencies": { + "html-element-attributes": "^1.0.0" + } + }, "node_modules/react-i18next": { "version": "13.2.2", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-13.2.2.tgz", @@ -9423,6 +10058,18 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "node_modules/react-number-format": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.0.tgz", + "integrity": "sha512-NWdICrqLhI7rAS8yUeLVd6Wr4cN7UjJ9IBTS0f/a9i7UB4x4Ti70kGnksBtZ7o4Z7YRbvCMMR/jQmkoOBa/4fg==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-plotly.js": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/react-plotly.js/-/react-plotly.js-2.6.0.tgz", @@ -9473,6 +10120,17 @@ } } }, + "node_modules/react-responsive-carousel": { + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", + "integrity": "sha512-pqJLsBaKHWJhw/ItODgbVoziR2z4lpcJg+YwmRlSk4rKH32VE633mAtZZ9kDXjy4wFO+pgUZmDKPsPe1fPmHCg==", + "peer": true, + "dependencies": { + "classnames": "^2.2.5", + "prop-types": "^15.5.8", + "react-easy-swipe": "^0.0.21" + } + }, "node_modules/react-router": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", @@ -10940,6 +11598,17 @@ "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" }, + "node_modules/ts-invariant": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", + "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ts-mixer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", @@ -11171,6 +11840,35 @@ "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==" }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "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/update-diff": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-diff/-/update-diff-1.1.0.tgz", @@ -11546,7 +12244,6 @@ "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" }, diff --git a/webapp/package.json b/webapp/package.json index 0438e2a827..0beca04e0a 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -13,6 +13,7 @@ "dependencies": { "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", + "@glideapps/glide-data-grid": "6.0.3", "@handsontable/react": "14.1.0", "@mui/icons-material": "5.14.11", "@mui/lab": "5.0.0-alpha.146", From 305ba8344801db4abff53e42e07a8d539d8e04ba Mon Sep 17 00:00:00 2001 From: hatim dinia Date: Fri, 21 Jun 2024 15:41:48 +0200 Subject: [PATCH 02/17] feat(tests): add `Vitest`, `React Testing Library`, and `JSDOM` setup --- webapp/package-lock.json | 1488 ++++++++++++++++++++++++++++++++++++- webapp/package.json | 15 +- webapp/src/tests/setup.ts | 17 + webapp/tsconfig.json | 1 + webapp/vite.config.ts | 9 +- 5 files changed, 1519 insertions(+), 11 deletions(-) create mode 100644 webapp/src/tests/setup.ts diff --git a/webapp/package-lock.json b/webapp/package-lock.json index e1b3d5dfe8..da7c61b485 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", - "@glideapps/glide-data-grid": "^6.0.3", + "@glideapps/glide-data-grid": "6.0.3", "@handsontable/react": "14.1.0", "@mui/icons-material": "5.14.11", "@mui/lab": "5.0.0-alpha.146", @@ -66,6 +66,9 @@ "xml-js": "1.6.11" }, "devDependencies": { + "@testing-library/jest-dom": "6.4.6", + "@testing-library/react": "16.0.0", + "@testing-library/user-event": "14.5.2", "@total-typescript/ts-reset": "0.5.1", "@types/d3": "5.16.0", "@types/debug": "4.1.9", @@ -87,10 +90,13 @@ "@types/react-window": "1.8.6", "@types/redux-logger": "3.0.10", "@types/swagger-ui-react": "4.18.1", + "@types/testing-library__jest-dom": "6.0.0", "@types/uuid": "9.0.4", "@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/parser": "6.14.0", "@vitejs/plugin-react-swc": "3.5.0", + "@vitest/coverage-v8": "^1.6.0", + "@vitest/ui": "^1.6.0", "eslint": "8.55.0", "eslint-config-prettier": "9.0.0", "eslint-plugin-jsdoc": "48.2.0", @@ -99,9 +105,11 @@ "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.5", "husky": "8.0.3", + "jsdom": "^24.1.0", "prettier": "3.0.3", "typescript": "5.2.2", - "vite": "5.0.8" + "vite": "5.0.8", + "vitest": "1.6.0" }, "engines": { "node": "18.16.1" @@ -116,6 +124,12 @@ "node": ">=0.10.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -591,6 +605,12 @@ "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, "node_modules/@braintree/sanitize-url": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", @@ -1291,6 +1311,27 @@ "react": "*" } }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -2039,6 +2080,12 @@ "pick-by-alias": "^1.2.0" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", + "dev": true + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -2249,6 +2296,12 @@ "win32" ] }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "node_modules/@sphinxxxx/color-conversion": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", @@ -3499,6 +3552,165 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@testing-library/dom": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", + "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.6.tgz", + "integrity": "sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/react": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz", + "integrity": "sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@total-typescript/ts-reset": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@total-typescript/ts-reset/-/ts-reset-0.5.1.tgz", @@ -3566,6 +3778,13 @@ "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==", "dev": true }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "peer": true + }, "node_modules/@types/d3": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.16.0.tgz", @@ -4098,6 +4317,16 @@ "@types/react": "*" } }, + "node_modules/@types/testing-library__jest-dom": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-6.0.0.tgz", + "integrity": "sha512-bnreXCgus6IIadyHNlN/oI5FfX4dWgvGhOPvpr7zzCYDGAPIfvyIoAozMBINmhmsVuqV0cncejF2y5KC7ScqOg==", + "deprecated": "This is a stub types definition. @testing-library/jest-dom provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "@testing-library/jest-dom": "*" + } + }, "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", @@ -4321,6 +4550,150 @@ "vite": "^4 || ^5" } }, + "node_modules/@vitest/coverage-v8": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.6.0.tgz", + "integrity": "sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.4", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.3", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "test-exclude": "^6.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.6.0" + } + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/ui": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.6.0.tgz", + "integrity": "sha512-k3Lyo+ONLOgylctiGovRKy7V4+dIN2yxstX3eY5cWFXH6WP+ooVX79YSyi0GagdTQzLmT43BF27T0s6dOIPBXA==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.0", + "fast-glob": "^3.3.2", + "fflate": "^0.8.1", + "flatted": "^3.2.9", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.6.0" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", @@ -4362,6 +4735,30 @@ "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==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -4419,6 +4816,15 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/array-bounds": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-bounds/-/array-bounds-1.0.1.tgz", @@ -4566,6 +4972,15 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", @@ -4814,6 +5229,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -4867,6 +5291,24 @@ "resolved": "https://registry.npmjs.org/canvas-hypertxt/-/canvas-hypertxt-1.0.3.tgz", "integrity": "sha512-+VsMpRr64jYgKq2IeFUNel3vCZH/IzS+iXSHxmUV3IUH5dXlC9xHz4AwtPZisDxZ5MWcuK0V+TXgPKFPiZnxzg==" }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4909,6 +5351,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/chevrotain": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-6.5.0.tgz", @@ -5080,6 +5534,12 @@ "typedarray": "^0.0.6" } }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -5259,6 +5719,24 @@ "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==" }, + "node_modules/cssstyle": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "dev": true, + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -5566,8 +6044,55 @@ "d3-transition": "1" } }, - "node_modules/debug": { - "version": "4.3.4", + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/debug": { + "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { @@ -5582,6 +6107,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", @@ -5597,6 +6128,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -5665,6 +6208,15 @@ "node": ">=0.4.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/detect-kerning": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-kerning/-/detect-kerning-2.1.2.tgz", @@ -5679,6 +6231,15 @@ "node": ">=8" } }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5703,6 +6264,13 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "peer": true + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -5823,6 +6391,18 @@ "once": "^1.4.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -6381,6 +6961,15 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -6397,6 +6986,41 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -6605,6 +7229,12 @@ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6909,6 +7539,15 @@ "resolved": "https://registry.npmjs.org/get-canvas-context/-/get-canvas-context-1.0.2.tgz", "integrity": "sha512-LnpfLf/TNzr9zVOGiIY6aKCz8EKuXmlYNV7CM2pUjBa/B+c2I15tS7KLySep75+FuerJdmArvJLcsAXWEy2H0A==" }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", @@ -7483,6 +8122,24 @@ "resolved": "https://registry.npmjs.org/html-element-attributes/-/html-element-attributes-1.3.1.tgz", "integrity": "sha512-UrRKgp5sQmRnDy4TEwAUsu14XBUlzKB8U3hjIYDjcZ3Hbp86Jtftzxfgrv6E/ii/h78tsaZwAnAE8HwnHr0dPA==" }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "node_modules/html-parse-stringify": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", @@ -7491,6 +8148,41 @@ "void-elements": "3.1.0" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, "node_modules/husky": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", @@ -7648,6 +8340,15 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -8052,6 +8753,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -8089,6 +8796,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -8207,6 +8926,56 @@ "node": ">=0.10.0" } }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz", + "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -8271,6 +9040,80 @@ "node": ">=12.0.0" } }, + "node_modules/jsdom": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", + "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "dev": true, + "dependencies": { + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.10", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.4", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.17.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -8440,6 +9283,22 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -8495,6 +9354,15 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lowlight": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", @@ -8519,6 +9387,51 @@ "node": ">=10" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/magicast": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz", + "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.4", + "@babel/types": "^7.24.0", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/map-limit": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", @@ -8630,6 +9543,12 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -8670,6 +9589,18 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -8682,7 +9613,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minim": { + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minim": { "version": "0.23.8", "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", @@ -8718,6 +9658,18 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "optional": true }, + "node_modules/mlly": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", + "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, "node_modules/mobius1-selectr": { "version": "2.4.13", "resolved": "https://registry.npmjs.org/mobius1-selectr/-/mobius1-selectr-2.4.13.tgz", @@ -8759,6 +9711,15 @@ "to-px": "^1.0.1" } }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8981,6 +9942,33 @@ "node": ">=6" } }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/number-is-integer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-integer/-/number-is-integer-1.0.1.tgz", @@ -9003,6 +9991,12 @@ "node": "*" } }, + "node_modules/nwsapi": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", + "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "dev": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9125,6 +10119,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", @@ -9261,6 +10270,18 @@ "resolved": "https://registry.npmjs.org/parse-unit/-/parse-unit-1.0.1.tgz", "integrity": "sha512-hrqldJHokR3Qj88EIlV/kAyAi/G5R2+R56TBANxNMy0uPlYcttx0jnMW6Yx5KsKPSbC3KddM/7qQm3+0wEXKxg==" }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/patch-package": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", @@ -9354,6 +10375,21 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pbf": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", @@ -9402,6 +10438,17 @@ "resolved": "https://registry.npmjs.org/pikaday/-/pikaday-1.8.2.tgz", "integrity": "sha512-TNtsE+34BIax3WtkB/qqu5uepV1McKYEgvL3kWzU7aqPCpMEN6rBF3AOwu4WCwAealWlBGobXny/9kJb49C1ew==" }, + "node_modules/pkg-types": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.1.tgz", + "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.0", + "pathe": "^1.1.2" + } + }, "node_modules/plotly.js": { "version": "2.26.1", "resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-2.26.1.tgz", @@ -9574,6 +10621,32 @@ "node": ">=6.0.0" } }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", @@ -9650,6 +10723,12 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -10314,6 +11393,19 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -10629,6 +11721,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true + }, "node_modules/rtl-css-js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", @@ -10729,6 +11827,18 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -10876,6 +11986,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/signum": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/signum/-/signum-1.0.0.tgz", @@ -10926,6 +12054,20 @@ "simple-concat": "^1.0.0" } }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -10944,9 +12086,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -11009,6 +12151,12 @@ "node": "*" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", @@ -11054,6 +12202,12 @@ "escodegen": "^2.1.0" } }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, "node_modules/stream-parser": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", @@ -11178,6 +12332,30 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11190,6 +12368,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, "node_modules/strongly-connected-components": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz", @@ -11360,6 +12556,12 @@ "immutable": "^3.8.1 || ^4.0.0-rc.1" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/synckit": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", @@ -11429,6 +12631,20 @@ "node": ">= 6" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -11463,16 +12679,40 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tinyqueue": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==" }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11534,6 +12774,39 @@ "topoquantize": "bin/topoquantize" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -11654,6 +12927,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -11787,6 +13069,12 @@ "node": "*" } }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -12033,6 +13321,93 @@ } } }, + "node_modules/vite-node": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -12051,6 +13426,18 @@ "pbf": "^3.2.1" } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/weak-map": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.8.tgz", @@ -12083,6 +13470,39 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -12182,6 +13602,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/world-calendars": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/world-calendars/-/world-calendars-1.0.3.tgz", @@ -12195,6 +13631,27 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", @@ -12219,6 +13676,21 @@ "xml-js": "bin/cli.js" } }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/webapp/package.json b/webapp/package.json index a49844ccc7..5fe6041835 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -8,7 +8,10 @@ "clean": "rm -rf dist node_modules/.vite", "dev": "vite", "lint": "tsc --noEmit && eslint . --ext ts,tsx --report-unused-disable-directives", - "preview": "vite preview" + "preview": "vite preview", + "test": "vitest", + "test:ui": "vitest --ui", + "coverage": "vitest run --coverage" }, "dependencies": { "@emotion/react": "11.11.1", @@ -69,6 +72,9 @@ "xml-js": "1.6.11" }, "devDependencies": { + "@testing-library/jest-dom": "6.4.6", + "@testing-library/react": "16.0.0", + "@testing-library/user-event": "14.5.2", "@total-typescript/ts-reset": "0.5.1", "@types/d3": "5.16.0", "@types/debug": "4.1.9", @@ -90,10 +96,13 @@ "@types/react-window": "1.8.6", "@types/redux-logger": "3.0.10", "@types/swagger-ui-react": "4.18.1", + "@types/testing-library__jest-dom": "6.0.0", "@types/uuid": "9.0.4", "@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/parser": "6.14.0", "@vitejs/plugin-react-swc": "3.5.0", + "@vitest/coverage-v8": "1.6.0", + "@vitest/ui": "^1.6.0", "eslint": "8.55.0", "eslint-config-prettier": "9.0.0", "eslint-plugin-jsdoc": "48.2.0", @@ -102,9 +111,11 @@ "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.5", "husky": "8.0.3", + "jsdom": "24.1.0", "prettier": "3.0.3", "typescript": "5.2.2", - "vite": "5.0.8" + "vite": "5.0.8", + "vitest": "1.6.0" }, "engines": { "node": "18.16.1" diff --git a/webapp/src/tests/setup.ts b/webapp/src/tests/setup.ts new file mode 100644 index 0000000000..d1e9ef6bae --- /dev/null +++ b/webapp/src/tests/setup.ts @@ -0,0 +1,17 @@ +import * as matchers from "@testing-library/jest-dom/matchers"; +import "@testing-library/jest-dom"; +import { cleanup } from "@testing-library/react"; +import { expect } from "vitest"; + +// Extend Vitest's expect function with jest-dom matchers for enhanced DOM assertions. +expect.extend(matchers); + +afterEach(() => { + cleanup(); +}); + +// Additional setup can include: +// - Mocks: Define global mocks for browser APIs like localStorage, fetch, etc. +// - Global Test Data: Setup common data used across multiple test files. +// - Configuration Settings: Adjust global settings for tests, such as timeouts or environment variables. +// - Cleanup: Implement global afterEach or beforeEach hooks for cleanup and setup between tests. diff --git a/webapp/tsconfig.json b/webapp/tsconfig.json index 1070a7d006..3a20f675ad 100644 --- a/webapp/tsconfig.json +++ b/webapp/tsconfig.json @@ -13,6 +13,7 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", + "types": ["vitest/globals", "vitest/jsdom"], /* Linting */ "strict": true, diff --git a/webapp/vite.config.ts b/webapp/vite.config.ts index 614e70c546..7cce8d327b 100644 --- a/webapp/vite.config.ts +++ b/webapp/vite.config.ts @@ -1,3 +1,4 @@ +/// import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; @@ -8,7 +9,7 @@ export default defineConfig(({ mode }) => { const isDesktopMode = mode === "desktop"; return { - // Serve the web app at the `/static` entry point on Desktop mode + // Serve the web app at the `/static` entry point on Desktop mode (cf. 'antarest/main.py') base: isDesktopMode ? "/static/" : "/", esbuild: { // Remove logs safely when building production bundle @@ -28,5 +29,11 @@ export default defineConfig(({ mode }) => { }, }, }, + test: { + globals: true, // Use the APIs globally + environment: "jsdom", + css: true, + setupFiles: "./src/tests/setup.ts", + }, }; }); From 68238fec870315cc881ece97e0fb29ebae630cc0 Mon Sep 17 00:00:00 2001 From: hatim dinia Date: Fri, 21 Jun 2024 15:43:41 +0200 Subject: [PATCH 03/17] ci(tests): add `Vitest` run to workflow --- .github/workflows/main.yml | 9 ++++++--- webapp/package-lock.json | 6 +++--- webapp/package.json | 2 +- webapp/tsconfig.node.json | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1316ff07ca..087221fa3c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,7 +38,7 @@ jobs: strategy: max-parallel: 9 matrix: - os: [ windows-latest, ubuntu-20.04 ] + os: [windows-latest, ubuntu-20.04] steps: - name: Checkout github repo (+ download lfs dependencies) @@ -69,7 +69,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-20.04 ] + os: [ubuntu-20.04] steps: - name: Checkout github repo uses: actions/checkout@v4 @@ -89,10 +89,13 @@ jobs: - name: Lint run: npm run lint working-directory: webapp + - name: Test + run: npm run test + working-directory: webapp sonarcloud: runs-on: ubuntu-20.04 - needs: [ python-test, npm-test ] + needs: [python-test, npm-test] steps: - uses: actions/checkout@v4 - name: Download python coverage report diff --git a/webapp/package-lock.json b/webapp/package-lock.json index da7c61b485..4aa82bb1c7 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -95,8 +95,8 @@ "@typescript-eslint/eslint-plugin": "6.14.0", "@typescript-eslint/parser": "6.14.0", "@vitejs/plugin-react-swc": "3.5.0", - "@vitest/coverage-v8": "^1.6.0", - "@vitest/ui": "^1.6.0", + "@vitest/coverage-v8": "1.6.0", + "@vitest/ui": "1.6.0", "eslint": "8.55.0", "eslint-config-prettier": "9.0.0", "eslint-plugin-jsdoc": "48.2.0", @@ -105,7 +105,7 @@ "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.5", "husky": "8.0.3", - "jsdom": "^24.1.0", + "jsdom": "24.1.0", "prettier": "3.0.3", "typescript": "5.2.2", "vite": "5.0.8", diff --git a/webapp/package.json b/webapp/package.json index 5fe6041835..5899ba243d 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -102,7 +102,7 @@ "@typescript-eslint/parser": "6.14.0", "@vitejs/plugin-react-swc": "3.5.0", "@vitest/coverage-v8": "1.6.0", - "@vitest/ui": "^1.6.0", + "@vitest/ui": "1.6.0", "eslint": "8.55.0", "eslint-config-prettier": "9.0.0", "eslint-plugin-jsdoc": "48.2.0", diff --git a/webapp/tsconfig.node.json b/webapp/tsconfig.node.json index 42872c59f5..b1b8569880 100644 --- a/webapp/tsconfig.node.json +++ b/webapp/tsconfig.node.json @@ -4,7 +4,8 @@ "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "types": ["vitest/globals", "vitest/jsdom"] }, "include": ["vite.config.ts"] } From 1cfeb8b04f87c726c0e4039873cb25c0374d52e1 Mon Sep 17 00:00:00 2001 From: hatim dinia Date: Mon, 24 Jun 2024 09:39:02 +0200 Subject: [PATCH 04/17] test(ui): ensure `App` component correctly renders within `Redux` and `MUI` providers --- webapp/src/index.test.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 webapp/src/index.test.tsx diff --git a/webapp/src/index.test.tsx b/webapp/src/index.test.tsx new file mode 100644 index 0000000000..6317806c00 --- /dev/null +++ b/webapp/src/index.test.tsx @@ -0,0 +1,19 @@ +import { render } from "@testing-library/react"; +import { Provider } from "react-redux"; +import { StyledEngineProvider } from "@mui/material"; +import App from "./components/App"; +import store from "./redux/store"; + +describe("Application Render", () => { + test("renders the App component with providers", () => { + const { getByText } = render( + + + + + , + ); + + expect(getByText("Antares Web")).toBeInTheDocument(); + }); +}); From b195aa0c293030c5112ee093ff0d12f925ebd309 Mon Sep 17 00:00:00 2001 From: mabw-rte <41002227+mabw-rte@users.noreply.github.com> Date: Tue, 25 Jun 2024 00:27:48 +0200 Subject: [PATCH 05/17] feat(api): do not allow areas, links or thermals deletion when referenced in a binding constraint (#2061) --- antarest/core/exceptions.py | 29 +++ .../business/binding_constraint_management.py | 13 +- antarest/study/model.py | 38 +++- antarest/study/service.py | 145 +++++++++---- antarest/study/web/study_data_blueprint.py | 1 + tests/core/test_exceptions.py | 25 +++ .../study_data_blueprint/test_thermal.py | 192 +++++++++++++++++- tests/integration/test_integration.py | 182 ++++++++++++++++- 8 files changed, 562 insertions(+), 63 deletions(-) create mode 100644 tests/core/test_exceptions.py diff --git a/antarest/core/exceptions.py b/antarest/core/exceptions.py index cf1b21d1a4..66859234fc 100644 --- a/antarest/core/exceptions.py +++ b/antarest/core/exceptions.py @@ -325,6 +325,35 @@ def __init__(self, is_variant: bool) -> None: super().__init__(HTTPStatus.EXPECTATION_FAILED, "Upgrade not supported for parent of variants") +class ReferencedObjectDeletionNotAllowed(HTTPException): + """ + Exception raised when a binding constraint is not allowed to be deleted because it references + other objects: areas, links or thermal clusters. + """ + + def __init__(self, object_id: str, binding_ids: t.Sequence[str], *, object_type: str) -> None: + """ + Initialize the exception. + + Args: + object_id: ID of the object that is not allowed to be deleted. + binding_ids: Binding constraints IDs that reference the object. + object_type: Type of the object that is not allowed to be deleted: area, link or thermal cluster. + """ + max_count = 10 + first_bcs_ids = ",\n".join(f"{i}- '{bc}'" for i, bc in enumerate(binding_ids[:max_count], 1)) + and_more = f",\nand {len(binding_ids) - max_count} more..." if len(binding_ids) > max_count else "." + message = ( + f"{object_type} '{object_id}' is not allowed to be deleted, because it is referenced" + f" in the following binding constraints:\n{first_bcs_ids}{and_more}" + ) + super().__init__(HTTPStatus.FORBIDDEN, message) + + def __str__(self) -> str: + """Return a string representation of the exception.""" + return self.detail + + class UnsupportedStudyVersion(HTTPException): def __init__(self, version: str) -> None: super().__init__( diff --git a/antarest/study/business/binding_constraint_management.py b/antarest/study/business/binding_constraint_management.py index 28881ef874..7f42bb7f59 100644 --- a/antarest/study/business/binding_constraint_management.py +++ b/antarest/study/business/binding_constraint_management.py @@ -501,13 +501,12 @@ def terms_to_coeffs(terms: t.Sequence[ConstraintTerm]) -> t.Dict[str, t.List[flo :return: A dictionary of term IDs mapped to a list of their coefficients. """ coeffs = {} - if terms is not None: - for term in terms: - if term.id and term.weight is not None: - coeffs[term.id] = [term.weight] - if term.offset: - coeffs[term.id].append(term.offset) - return coeffs + for term in terms: + if term.id and term.weight is not None: + coeffs[term.id] = [term.weight] + if term.offset: + coeffs[term.id].append(term.offset) + return coeffs def get_binding_constraint(self, study: Study, bc_id: str) -> ConstraintOutput: """ diff --git a/antarest/study/model.py b/antarest/study/model.py index ad3d1f0fb4..4eff8109ab 100644 --- a/antarest/study/model.py +++ b/antarest/study/model.py @@ -426,13 +426,37 @@ class ExportFormat(str, enum.Enum): TAR_GZ = "application/tar+gz" JSON = "application/json" - @staticmethod - def from_dto(data: str) -> "ExportFormat": - if data == "application/zip": - return ExportFormat.ZIP - if data == "application/tar+gz": - return ExportFormat.TAR_GZ - return ExportFormat.JSON + @classmethod + def from_dto(cls, accept_header: str) -> "ExportFormat": + """ + Convert the "Accept" header to the corresponding content type. + + Args: + accept_header: Value of the "Accept" header. + + Returns: + The corresponding content type: ZIP, TAR_GZ or JSON. + By default, JSON is returned if the format is not recognized. + For instance, if the "Accept" header is "*/*", JSON is returned. + """ + mapping = { + "application/zip": ExportFormat.ZIP, + "application/tar+gz": ExportFormat.TAR_GZ, + "application/json": ExportFormat.JSON, + } + return mapping.get(accept_header, ExportFormat.JSON) + + @property + def suffix(self) -> str: + """ + Returns the file suffix associated with the format: ".zip", ".tar.gz" or ".json". + """ + mapping = { + ExportFormat.ZIP: ".zip", + ExportFormat.TAR_GZ: ".tar.gz", + ExportFormat.JSON: ".json", + } + return mapping[self] class StudyDownloadDTO(BaseModel): diff --git a/antarest/study/service.py b/antarest/study/service.py index 0330992da2..494e7d2f2f 100644 --- a/antarest/study/service.py +++ b/antarest/study/service.py @@ -24,6 +24,7 @@ CommandApplicationError, IncorrectPathError, NotAManagedStudyException, + ReferencedObjectDeletionNotAllowed, StudyDeletionNotAllowed, StudyNotFoundError, StudyTypeUnsupported, @@ -56,7 +57,7 @@ from antarest.study.business.areas.renewable_management import RenewableManager from antarest.study.business.areas.st_storage_management import STStorageManager from antarest.study.business.areas.thermal_management import ThermalManager -from antarest.study.business.binding_constraint_management import BindingConstraintManager +from antarest.study.business.binding_constraint_management import BindingConstraintManager, ConstraintFilters, LinkTerm from antarest.study.business.config_management import ConfigManager from antarest.study.business.correlation_management import CorrelationManager from antarest.study.business.district_manager import DistrictManager @@ -686,7 +687,7 @@ def create_study( id=sid, name=study_name, workspace=DEFAULT_WORKSPACE_NAME, - path=study_path, + path=str(study_path), created_at=datetime.utcnow(), updated_at=datetime.utcnow(), version=version or NEW_DEFAULT_STUDY_VERSION, @@ -1187,13 +1188,13 @@ def download_outputs( """ Download outputs Args: - study_id: study Id - output_id: output id - data: Json parameters - use_task: use task or not - filetype: type of returning file, - tmp_export_file: temporary file (if use_task is false), - params: request parameters + study_id: study ID. + output_id: output ID. + data: Json parameters. + use_task: use task or not. + filetype: type of returning file,. + tmp_export_file: temporary file (if `use_task` is false),. + params: request parameters. Returns: CSV content file @@ -1202,35 +1203,33 @@ def download_outputs( study = self.get_study(study_id) assert_permission(params.user, study, StudyPermissionType.READ) self._assert_study_unarchived(study) - logger.info( - f"Study {study_id} output download asked by {params.get_user_id()}", - ) + logger.info(f"Study {study_id} output download asked by {params.get_user_id()}") if use_task: logger.info(f"Exporting {output_id} from study {study_id}") export_name = f"Study filtered output {study.name}/{output_id} export" export_file_download = self.file_transfer_manager.request_download( - f"{study.name}-{study_id}-{output_id}_filtered.{'tar.gz' if filetype == ExportFormat.TAR_GZ else 'zip'}", + f"{study.name}-{study_id}-{output_id}_filtered{filetype.suffix}", export_name, params.user, ) export_path = Path(export_file_download.path) export_id = export_file_download.id - def export_task(notifier: TaskUpdateNotifier) -> TaskResult: + def export_task(_notifier: TaskUpdateNotifier) -> TaskResult: try: - study = self.get_study(study_id) - stopwatch = StopWatch() - matrix = StudyDownloader.build( - self.storage_service.get_storage(study).get_raw(study), + _study = self.get_study(study_id) + _stopwatch = StopWatch() + _matrix = StudyDownloader.build( + self.storage_service.get_storage(_study).get_raw(_study), output_id, data, ) - stopwatch.log_elapsed( + _stopwatch.log_elapsed( lambda x: logger.info(f"Study {study_id} filtered output {output_id} built in {x}s") ) - StudyDownloader.export(matrix, filetype, export_path) - stopwatch.log_elapsed( + StudyDownloader.export(_matrix, filetype, export_path) + _stopwatch.log_elapsed( lambda x: logger.info(f"Study {study_id} filtered output {output_id} exported in {x}s") ) self.file_transfer_manager.set_ready(export_id) @@ -1240,7 +1239,7 @@ def export_task(notifier: TaskUpdateNotifier) -> TaskResult: ) except Exception as e: self.file_transfer_manager.fail(export_id, str(e)) - raise e + raise task_id = self.task_service.add_task( export_task, @@ -1265,17 +1264,18 @@ def export_task(notifier: TaskUpdateNotifier) -> TaskResult: stopwatch.log_elapsed( lambda x: logger.info(f"Study {study_id} filtered output {output_id} exported in {x}s") ) - return FileResponse( - tmp_export_file, - headers=( - {"Content-Disposition": "inline"} - if filetype == ExportFormat.JSON - else { - "Content-Disposition": f'attachment; filename="output-{output_id}.{"tar.gz" if filetype == ExportFormat.TAR_GZ else "zip"}' - } - ), - media_type=filetype, - ) + + if filetype == ExportFormat.JSON: + headers = {"Content-Disposition": "inline"} + elif filetype == ExportFormat.TAR_GZ: + headers = {"Content-Disposition": f'attachment; filename="output-{output_id}.tar.gz'} + elif filetype == ExportFormat.ZIP: + headers = {"Content-Disposition": f'attachment; filename="output-{output_id}.zip'} + else: # pragma: no cover + raise NotImplementedError(f"Export format {filetype} is not supported") + + return FileResponse(tmp_export_file, headers=headers, media_type=filetype) + else: json_response = json.dumps( matrix.dict(), @@ -1314,26 +1314,20 @@ def set_sim_reference( params: RequestParameters, ) -> None: """ - Set simulation as the reference output + Set simulation as the reference output. + Args: - study_id: study Id - output_id: output id - status: state of the reference status + study_id: study ID. + output_id: The ID of the output to set as reference. + status: state of the reference status. params: request parameters - - Returns: None - """ study = self.get_study(study_id) assert_permission(params.user, study, StudyPermissionType.WRITE) self._assert_study_unarchived(study) logger.info( - "output %s set by user %s as reference (%b) for study %s", - output_id, - params.get_user_id(), - status, - study_id, + f"output {output_id} set by user {params.get_user_id()} as reference ({status}) for study {study_id}" ) self.storage_service.get_storage(study).set_reference_output(study, output_id, status) @@ -1855,9 +1849,27 @@ def update_thermal_cluster_metadata( return self.areas.update_thermal_cluster_metadata(study, area_id, clusters_metadata) def delete_area(self, uuid: str, area_id: str, params: RequestParameters) -> None: + """ + Delete area from study if it is not referenced by a binding constraint, + otherwise raise an HTTP 403 Forbidden error. + + Args: + uuid: The study ID. + area_id: The area ID to delete. + params: The request parameters used to check user permissions. + + Raises: + ReferencedObjectDeletionNotAllowed: If the area is referenced by a binding constraint. + """ study = self.get_study(uuid) assert_permission(params.user, study, StudyPermissionType.WRITE) self._assert_study_unarchived(study) + referencing_binding_constraints = self.binding_constraint_manager.get_binding_constraints( + study, ConstraintFilters(area_name=area_id) + ) + if referencing_binding_constraints: + binding_ids = [bc.id for bc in referencing_binding_constraints] + raise ReferencedObjectDeletionNotAllowed(area_id, binding_ids, object_type="Area") self.areas.delete_area(study, area_id) self.event_bus.push( Event( @@ -1874,9 +1886,29 @@ def delete_link( area_to: str, params: RequestParameters, ) -> None: + """ + Delete link from study if it is not referenced by a binding constraint, + otherwise raise an HTTP 403 Forbidden error. + + Args: + uuid: The study ID. + area_from: The area from which the link starts. + area_to: The area to which the link ends. + params: The request parameters used to check user permissions. + + Raises: + ReferencedObjectDeletionNotAllowed: If the link is referenced by a binding constraint. + """ study = self.get_study(uuid) assert_permission(params.user, study, StudyPermissionType.WRITE) self._assert_study_unarchived(study) + link_id = LinkTerm(area1=area_from, area2=area_to).generate_id() + referencing_binding_constraints = self.binding_constraint_manager.get_binding_constraints( + study, ConstraintFilters(link_id=link_id) + ) + if referencing_binding_constraints: + binding_ids = [bc.id for bc in referencing_binding_constraints] + raise ReferencedObjectDeletionNotAllowed(link_id, binding_ids, object_type="Link") self.links.delete_link(study, area_from, area_to) self.event_bus.push( Event( @@ -2518,3 +2550,26 @@ def get_matrix_with_index_and_header( ) return df_matrix + + def asserts_no_thermal_in_binding_constraints( + self, study: Study, area_id: str, cluster_ids: t.Sequence[str] + ) -> None: + """ + Check that no cluster is referenced in a binding constraint, otherwise raise an HTTP 403 Forbidden error. + + Args: + study: input study for which an update is to be committed + area_id: area ID to be checked + cluster_ids: IDs of the thermal clusters to be checked + + Raises: + ReferencedObjectDeletionNotAllowed: if a cluster is referenced in a binding constraint + """ + + for cluster_id in cluster_ids: + ref_bcs = self.binding_constraint_manager.get_binding_constraints( + study, ConstraintFilters(cluster_id=f"{area_id}.{cluster_id}") + ) + if ref_bcs: + binding_ids = [bc.id for bc in ref_bcs] + raise ReferencedObjectDeletionNotAllowed(cluster_id, binding_ids, object_type="Cluster") diff --git a/antarest/study/web/study_data_blueprint.py b/antarest/study/web/study_data_blueprint.py index e84029ff8f..43d71400d5 100644 --- a/antarest/study/web/study_data_blueprint.py +++ b/antarest/study/web/study_data_blueprint.py @@ -2185,6 +2185,7 @@ def delete_thermal_clusters( ) request_params = RequestParameters(user=current_user) study = study_service.check_study_access(uuid, StudyPermissionType.WRITE, request_params) + study_service.asserts_no_thermal_in_binding_constraints(study, area_id, cluster_ids) study_service.thermal_manager.delete_clusters(study, area_id, cluster_ids) @bp.get( diff --git a/tests/core/test_exceptions.py b/tests/core/test_exceptions.py new file mode 100644 index 0000000000..86892187a0 --- /dev/null +++ b/tests/core/test_exceptions.py @@ -0,0 +1,25 @@ +from antarest.core.exceptions import ReferencedObjectDeletionNotAllowed + + +class TestReferencedObjectDeletionNotAllowed: + def test_few_binding_constraints(self) -> None: + object_id = "france" + binding_ids = ["bc1", "bc2"] + object_type = "Area" + exception = ReferencedObjectDeletionNotAllowed(object_id, binding_ids, object_type=object_type) + message = str(exception) + assert f"{object_type} '{object_id}'" in message + assert "bc1" in message + assert "bc2" in message + assert "more..." not in message + + def test_many_binding_constraints(self) -> None: + object_id = "france" + binding_ids = [f"bc{i}" for i in range(1, 50)] + object_type = "Area" + exception = ReferencedObjectDeletionNotAllowed(object_id, binding_ids, object_type=object_type) + message = str(exception) + assert f"{object_type} '{object_id}'" in message + assert "bc1" in message + assert "bc2" in message + assert "more..." in message diff --git a/tests/integration/study_data_blueprint/test_thermal.py b/tests/integration/study_data_blueprint/test_thermal.py index e3f62eca1e..c294d0c235 100644 --- a/tests/integration/study_data_blueprint/test_thermal.py +++ b/tests/integration/study_data_blueprint/test_thermal.py @@ -646,7 +646,26 @@ def test_lifecycle( ) assert res.status_code in {200, 201}, res.json() - # To delete a thermal cluster, we need to provide its ID. + # verify that we can't delete the thermal cluster because it is referenced in a binding constraint + res = client.request( + "DELETE", + f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + headers={"Authorization": f"Bearer {user_access_token}"}, + json=[fr_gas_conventional_id], + ) + assert res.status_code == 403, res.json() + description = res.json()["description"] + assert all([elm in description for elm in [fr_gas_conventional, "binding constraint"]]) + assert res.json()["exception"] == "ReferencedObjectDeletionNotAllowed" + + # delete the binding constraint + res = client.delete( + f"/v1/studies/{study_id}/bindingconstraints/{bc_obj['name']}", + headers={"Authorization": f"Bearer {user_access_token}"}, + ) + assert res.status_code == 200, res.json() + + # Now we can delete the thermal cluster res = client.request( "DELETE", f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", @@ -654,9 +673,8 @@ def test_lifecycle( json=[fr_gas_conventional_id], ) assert res.status_code == 204, res.json() - assert res.text in {"", "null"} # Old FastAPI versions return 'null'. - # When we delete a thermal cluster, we should also delete the binding constraints that reference it. + # check that the binding constraint has been deleted # noinspection SpellCheckingInspection res = client.get( f"/v1/studies/{study_id}/bindingconstraints", @@ -1029,3 +1047,171 @@ def test_variant_lifecycle(self, client: TestClient, user_access_token: str, var "replace_matrix", "remove_cluster", ] + + def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: str, study_id: str) -> None: + """ + Test that creating a thermal cluster with invalid properties raises a validation error. + """ + + client.headers = {"Authorization": f"Bearer {user_access_token}"} + + # Create an area "area_1" in the study + res = client.post( + f"/v1/studies/{study_id}/areas", + json={ + "name": "area_1", + "type": "AREA", + "metadata": {"country": "FR"}, + }, + ) + assert res.status_code == 200, res.json() + + # Create an area "area_2" in the study + res = client.post( + f"/v1/studies/{study_id}/areas", + json={ + "name": "area_2", + "type": "AREA", + "metadata": {"country": "DE"}, + }, + ) + assert res.status_code == 200, res.json() + + # Create an area "area_3" in the study + res = client.post( + f"/v1/studies/{study_id}/areas", + json={ + "name": "area_3", + "type": "AREA", + "metadata": {"country": "ES"}, + }, + ) + assert res.status_code == 200, res.json() + + # Create a thermal cluster in the study for area_1 + res = client.post( + f"/v1/studies/{study_id}/areas/area_1/clusters/thermal", + json={ + "name": "cluster_1", + "group": "Nuclear", + "unitCount": 13, + "nominalCapacity": 42500, + "marginalCost": 0.1, + }, + ) + assert res.status_code == 200, res.json() + + # Create a thermal cluster in the study for area_2 + res = client.post( + f"/v1/studies/{study_id}/areas/area_2/clusters/thermal", + json={ + "name": "cluster_2", + "group": "Nuclear", + "unitCount": 13, + "nominalCapacity": 42500, + "marginalCost": 0.1, + }, + ) + assert res.status_code == 200, res.json() + + # Create a thermal cluster in the study for area_3 + res = client.post( + f"/v1/studies/{study_id}/areas/area_3/clusters/thermal", + json={ + "name": "cluster_3", + "group": "Nuclear", + "unitCount": 13, + "nominalCapacity": 42500, + "marginalCost": 0.1, + }, + ) + assert res.status_code == 200, res.json() + + # add a binding constraint that references the thermal cluster in area_1 + bc_obj = { + "name": "bc_1", + "enabled": True, + "time_step": "hourly", + "operator": "less", + "terms": [ + { + "id": "area_1.cluster_1", + "weight": 2, + "offset": 5, + "data": {"area": "area_1", "cluster": "cluster_1"}, + } + ], + } + res = client.post( + f"/v1/studies/{study_id}/bindingconstraints", + json=bc_obj, + ) + assert res.status_code == 200, res.json() + + # add a binding constraint that references the thermal cluster in area_2 + bc_obj = { + "name": "bc_2", + "enabled": True, + "time_step": "hourly", + "operator": "less", + "terms": [ + { + "id": "area_2.cluster_2", + "weight": 2, + "offset": 5, + "data": {"area": "area_2", "cluster": "cluster_2"}, + } + ], + } + res = client.post( + f"/v1/studies/{study_id}/bindingconstraints", + json=bc_obj, + ) + assert res.status_code == 200, res.json() + + # check that deleting the thermal cluster in area_1 fails + res = client.delete( + f"/v1/studies/{study_id}/areas/area_1/clusters/thermal", + json=["cluster_1"], + ) + assert res.status_code == 403, res.json() + + # now delete the binding constraint that references the thermal cluster in area_1 + res = client.delete( + f"/v1/studies/{study_id}/bindingconstraints/bc_1", + ) + assert res.status_code == 200, res.json() + + # check that deleting the thermal cluster in area_1 succeeds + res = client.delete( + f"/v1/studies/{study_id}/areas/area_1/clusters/thermal", + json=["cluster_1"], + ) + assert res.status_code == 204, res.json() + + # check that deleting the thermal cluster in area_2 fails + res = client.delete( + f"/v1/studies/{study_id}/areas/area_2/clusters/thermal", + json=["cluster_2"], + ) + assert res.status_code == 403, res.json() + + # now delete the binding constraint that references the thermal cluster in area_2 + res = client.delete( + f"/v1/studies/{study_id}/bindingconstraints/bc_2", + ) + assert res.status_code == 200, res.json() + + # check that deleting the thermal cluster in area_2 succeeds + res = client.delete( + f"/v1/studies/{study_id}/areas/area_2/clusters/thermal", + json=["cluster_2"], + ) + assert res.status_code == 204, res.json() + + # check that deleting the thermal cluster in area_3 succeeds + res = client.delete( + f"/v1/studies/{study_id}/areas/area_3/clusters/thermal", + json=["cluster_3"], + ) + assert res.status_code == 204, res.json() diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 55e182c7d3..fa0d4d418c 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -1427,8 +1427,20 @@ def test_area_management(client: TestClient, admin_access_token: str) -> None: }, } + # check that at this stage the area cannot be deleted as it is referenced in binding constraint 1 result = client.delete(f"/v1/studies/{study_id}/areas/area%201") - assert result.status_code == 200 + assert result.status_code == 403, res.json() + # verify the error message + description = result.json()["description"] + assert all([elm in description for elm in ["area 1", "binding constraint 1"]]) + # check the exception + assert result.json()["exception"] == "ReferencedObjectDeletionNotAllowed" + + # delete binding constraint 1 + client.delete(f"/v1/studies/{study_id}/bindingconstraints/binding%20constraint%201") + # check now that we can delete the area 1 + result = client.delete(f"/v1/studies/{study_id}/areas/area%201") + assert result.status_code == 200, res.json() res_areas = client.get(f"/v1/studies/{study_id}/areas") assert res_areas.json() == [ { @@ -1701,3 +1713,171 @@ def test_copy(client: TestClient, admin_access_token: str, study_id: str) -> Non res = client.get(f"/v1/studies/{copied.json()}").json() assert res["groups"] == [] assert res["public_mode"] == "READ" + + +def test_areas_deletion_with_binding_constraints(client: TestClient, user_access_token: str, study_id: str) -> None: + """ + Test the deletion of areas that are referenced in binding constraints. + """ + + # set client headers to user access token + client.headers = {"Authorization": f"Bearer {user_access_token}"} + + area1_id = "france" + area2_id = "germany" + cluster_id = "nuclear power plant" + + constraint_terms = [ + { + # Link between two areas + "data": {"area1": area1_id, "area2": area2_id}, + "id": f"{area1_id}%{area2_id}", + "offset": 2, + "weight": 1.0, + }, + { + # Cluster in an area + "data": {"area": area1_id, "cluster": cluster_id.lower()}, + "id": f"{area1_id}.{cluster_id.lower()}", + "offset": 2, + "weight": 1.0, + }, + ] + + for constraint_term in constraint_terms: + # Create an area "area_1" in the study + res = client.post( + f"/v1/studies/{study_id}/areas", + json={"name": area1_id.title(), "type": "AREA", "metadata": {"country": "FR"}}, + ) + res.raise_for_status() + + if set(constraint_term["data"]) == {"area1", "area2"}: + # Create a second area and a link between the two areas + res = client.post( + f"/v1/studies/{study_id}/areas", + json={"name": area2_id.title(), "type": "AREA", "metadata": {"country": "DE"}}, + ) + res.raise_for_status() + res = client.post( + f"/v1/studies/{study_id}/links", + json={"area1": area1_id, "area2": area2_id}, + ) + res.raise_for_status() + + elif set(constraint_term["data"]) == {"area", "cluster"}: + # Create a cluster in the first area + res = client.post( + f"/v1/studies/{study_id}/areas/{area1_id}/clusters/thermal", + json={"name": cluster_id.title(), "group": "Nuclear"}, + ) + res.raise_for_status() + + else: + raise NotImplementedError(f"Unsupported constraint term: {constraint_term}") + + # create a binding constraint that references the link + bc_id = "bc_1" + bc_obj = { + "name": bc_id, + "enabled": True, + "time_step": "daily", + "operator": "less", + "terms": [constraint_term], + } + res = client.post(f"/v1/studies/{study_id}/bindingconstraints", json=bc_obj) + res.raise_for_status() + + if set(constraint_term["data"]) == {"area1", "area2"}: + areas_to_delete = [area1_id, area2_id] + elif set(constraint_term["data"]) == {"area", "cluster"}: + areas_to_delete = [area1_id] + else: + raise NotImplementedError(f"Unsupported constraint term: {constraint_term}") + + for area_id in areas_to_delete: + # try to delete the areas + res = client.delete(f"/v1/studies/{study_id}/areas/{area_id}") + assert res.status_code == 403, res.json() + description = res.json()["description"] + assert all([elm in description for elm in [area_id, bc_id]]) + assert res.json()["exception"] == "ReferencedObjectDeletionNotAllowed" + + # delete the binding constraint + res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}") + assert res.status_code == 200, res.json() + + for area_id in areas_to_delete: + # delete the area + res = client.delete(f"/v1/studies/{study_id}/areas/{area_id}") + assert res.status_code == 200, res.json() + + +def test_links_deletion_with_binding_constraints(client: TestClient, user_access_token: str, study_id: str) -> None: + """ + Test the deletion of links that are referenced in binding constraints. + """ + + # set client headers to user access token + client.headers = {"Authorization": f"Bearer {user_access_token}"} + + # Create an area "area_1" in the study + res = client.post( + f"/v1/studies/{study_id}/areas", + json={ + "name": "area_1", + "type": "AREA", + "metadata": {"country": "FR"}, + }, + ) + assert res.status_code == 200, res.json() + + # Create an area "area_2" in the study + res = client.post( + f"/v1/studies/{study_id}/areas", + json={ + "name": "area_2", + "type": "AREA", + "metadata": {"country": "DE"}, + }, + ) + assert res.status_code == 200, res.json() + + # create a link between the two areas + res = client.post( + f"/v1/studies/{study_id}/links", + json={"area1": "area_1", "area2": "area_2"}, + ) + assert res.status_code == 200, res.json() + + # create a binding constraint that references the link + bc_obj = { + "name": "bc_1", + "enabled": True, + "time_step": "hourly", + "operator": "less", + "terms": [ + { + "id": "area_1%area_2", + "weight": 2, + "data": {"area1": "area_1", "area2": "area_2"}, + } + ], + } + res = client.post(f"/v1/studies/{study_id}/bindingconstraints", json=bc_obj) + assert res.status_code == 200, res.json() + + # try to delete the link before deleting the binding constraint + res = client.delete(f"/v1/studies/{study_id}/links/area_1/area_2") + assert res.status_code == 403, res.json() + description = res.json()["description"] + assert all([elm in description for elm in ["area_1%area_2", "bc_1"]]) + assert res.json()["exception"] == "ReferencedObjectDeletionNotAllowed" + + # delete the binding constraint + res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/bc_1") + assert res.status_code == 200, res.json() + + # delete the link + res = client.delete(f"/v1/studies/{study_id}/links/area_1/area_2") + assert res.status_code == 200, res.json() From b6d778d00ff44c12122d15f9511c7864d8091869 Mon Sep 17 00:00:00 2001 From: MartinBelthle Date: Tue, 25 Jun 2024 15:09:01 +0200 Subject: [PATCH 06/17] feat(outputs): build outputs tree based on filesystem (#2064) Solves [ANT-1306] --- .../filesystem/common/area_matrix_list.py | 47 +- .../root/input/{load => commons}/__init__.py | 0 .../root/input/commons/prepro_series.py | 52 + .../model/filesystem/root/input/input.py | 10 +- .../input/link/area/capacities/capacities.py | 2 +- .../model/filesystem/root/input/load/load.py | 46 - .../root/input/renewables/clusters.py | 2 +- .../filesystem/root/input/solar/__init__.py | 0 .../filesystem/root/input/solar/solar.py | 46 - .../root/input/thermal/cluster/area/area.py | 2 +- .../root/input/thermal/prepro/area/area.py | 2 +- .../root/input/thermal/series/area/area.py | 2 +- .../filesystem/root/input/wind/__init__.py | 0 .../model/filesystem/root/input/wind/wind.py | 46 - .../output/simulation/mode/common/area.py | 78 +- .../output/simulation/mode/common/areas.py | 29 +- .../simulation/mode/common/binding_const.py | 16 +- .../output/simulation/mode/common/link.py | 40 +- .../output/simulation/mode/common/links.py | 33 +- .../root/output/simulation/mode/common/set.py | 38 +- .../mode/{mcall/mcall.py => common/utils.py} | 23 +- .../root/output/simulation/mode/economy.py | 9 +- .../root/output/simulation/mode/mcall/grid.py | 10 +- .../output/simulation/mode/mcind/mcind.py | 10 +- .../root/output/simulation/mode/mcind/scn.py | 23 - .../root/output/simulation/simulation.py | 20 +- .../simulation/ts_generator/ts_generator.py | 25 +- .../simulation/ts_numbers/ts_numbers.py | 43 +- examples/studies/STA-mini.zip | Bin 481559 -> 704805 bytes tests/helpers.py | 3 + .../storage/integration/data/set_id_annual.py | 327 ++ .../integration/data/set_values_monthly.py | 4206 +++++++++++++++++ tests/storage/integration/test_STA_mini.py | 48 +- tests/storage/integration/test_exporter.py | 2 +- .../simulation/mode/common/test_area.py | 86 +- .../mode/common/test_binding_const.py | 33 +- .../simulation/mode/common/test_link.py | 51 +- .../output/simulation/mode/common/test_set.py | 52 +- tests/storage/repository/filesystem/utils.py | 2 +- 39 files changed, 4845 insertions(+), 619 deletions(-) rename antarest/study/storage/rawstudy/model/filesystem/root/input/{load => commons}/__init__.py (100%) create mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/input/commons/prepro_series.py delete mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/input/load/load.py delete mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/input/solar/__init__.py delete mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/input/solar/solar.py delete mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/input/wind/__init__.py delete mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/input/wind/wind.py rename antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/{mcall/mcall.py => common/utils.py} (58%) delete mode 100644 antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/scn.py create mode 100644 tests/storage/integration/data/set_id_annual.py create mode 100644 tests/storage/integration/data/set_values_monthly.py diff --git a/antarest/study/storage/rawstudy/model/filesystem/common/area_matrix_list.py b/antarest/study/storage/rawstudy/model/filesystem/common/area_matrix_list.py index 0191b866d1..8bc1b5a497 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/common/area_matrix_list.py +++ b/antarest/study/storage/rawstudy/model/filesystem/common/area_matrix_list.py @@ -6,6 +6,8 @@ from antarest.study.storage.rawstudy.model.filesystem.inode import TREE, INode from antarest.study.storage.rawstudy.model.filesystem.matrix.input_series_matrix import InputSeriesMatrix +TXT_PATTERN = "*.txt" + class AreaMatrixList(FolderNode): """ @@ -60,14 +62,17 @@ def build(self) -> TREE: A dictionary of child nodes, where the key is the matrix file name and the value is the corresponding :class:`InputSeriesMatrix` node. """ - children: TREE = { - f"{self.prefix}{area}": self.matrix_class( - self.context, - self.config.next_file(f"{self.prefix}{area}.txt"), - **self.additional_matrix_params, + children: TREE = {} + if self.prefix: # Corresponds to the inputs + files = self.config.area_names() + else: # Corresponds to the outputs + files = [d.with_suffix("").name for d in self.config.path.iterdir()] + + for file in files: + name = f"{self.prefix}{file}" + children[name] = self.matrix_class( + self.context, self.config.next_file(f"{name}.txt"), **self.additional_matrix_params ) - for area in self.config.area_names() - } return children @@ -105,7 +110,7 @@ def build(self) -> TREE: """Builds the folder structure and creates child nodes representing each matrix file.""" return { file.stem: self.matrix_class(self.context, self.config.next_file(file.name)) - for file in self.config.path.glob("*.txt") + for file in self.config.path.glob(TXT_PATTERN) } @@ -124,15 +129,28 @@ def __init__( def build(self) -> TREE: # Note that cluster IDs are case-insensitive, but series IDs are in lower case. # For instance, if your cluster ID is "Base", then the series ID will be "base". - series_ids = map(str.lower, self.config.get_thermal_ids(self.area)) - children: TREE = { - series_id: self.matrix_class(self.context, self.config.next_file(f"{series_id}.txt")) - for series_id in series_ids + series_files = self.config.path.glob(TXT_PATTERN) + return { + series.stem: self.matrix_class(self.context, self.config.next_file(series.name)) for series in series_files } - return children class AreaMultipleMatrixList(FolderNode): + """ + Node representing a folder structure containing multiple matrix files for each area. + + Example of tree structure: + + .. code-block:: text + + ts-numbers/thermal + ├── at + │ ├── cluster_gas.txt + │ └── cluster2_gas.txt + └── be + └── cluster_nuclear.txt + """ + def __init__( self, context: ContextServer, @@ -156,6 +174,7 @@ def __init__( self.matrix_class = matrix_class def build(self) -> TREE: + folders = [d.name for d in self.config.path.iterdir() if d.is_dir()] children: TREE = { area: self.klass( self.context, @@ -163,6 +182,6 @@ def build(self) -> TREE: area, self.matrix_class, ) - for area in self.config.area_names() + for area in folders } return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/load/__init__.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/commons/__init__.py similarity index 100% rename from antarest/study/storage/rawstudy/model/filesystem/root/input/load/__init__.py rename to antarest/study/storage/rawstudy/model/filesystem/root/input/commons/__init__.py diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/commons/prepro_series.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/commons/prepro_series.py new file mode 100644 index 0000000000..b6e8f79c54 --- /dev/null +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/commons/prepro_series.py @@ -0,0 +1,52 @@ +from antarest.study.storage.rawstudy.model.filesystem.common.area_matrix_list import AreaMatrixList +from antarest.study.storage.rawstudy.model.filesystem.common.prepro import InputPrepro +from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig +from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer +from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode +from antarest.study.storage.rawstudy.model.filesystem.inode import TREE +from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import default_scenario_hourly + + +class InputPreproSeries(FolderNode): + def __init__(self, context: ContextServer, config: FileStudyTreeConfig, prefix: str): + """ + Represents a folder structure, which contains a "prepro" and a time series structure. + + Example of tree structure: + + .. code-block:: text + + input/load/ + ├── prepro + │ ├── correlation.ini + │ ├── store_in + │ │ ├── conversion.txt + │ │ ├── data.txt + │ │ ├── k.txt + │ │ ├── settings.ini + │ │ └── translation.txt + │ └── store_out + │ ├── conversion.txt + │ ├── data.txt + │ ├── k.txt + │ ├── settings.ini + │ └── translation.txt + └── series + ├── load_store_in.txt + └── load_store_out.txt + """ + + super().__init__(context, config) + self.prefix = prefix + + def build(self) -> TREE: + children: TREE = { + "prepro": InputPrepro(self.context, self.config.next_file("prepro")), + "series": AreaMatrixList( + self.context, + self.config.next_file("series"), + prefix=self.prefix, + additional_matrix_params={"default_empty": default_scenario_hourly}, + ), + } + return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/input.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/input.py index 91752b440e..fe22590f62 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/input.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/input.py @@ -5,16 +5,14 @@ from antarest.study.storage.rawstudy.model.filesystem.root.input.bindingconstraints.bindingcontraints import ( BindingConstraints, ) +from antarest.study.storage.rawstudy.model.filesystem.root.input.commons.prepro_series import InputPreproSeries from antarest.study.storage.rawstudy.model.filesystem.root.input.hydro.hydro import InputHydro from antarest.study.storage.rawstudy.model.filesystem.root.input.link.link import InputLink -from antarest.study.storage.rawstudy.model.filesystem.root.input.load.load import InputLoad from antarest.study.storage.rawstudy.model.filesystem.root.input.miscgen.miscgen import InputMiscGen from antarest.study.storage.rawstudy.model.filesystem.root.input.renewables.renewable import ClusteredRenewables from antarest.study.storage.rawstudy.model.filesystem.root.input.reserves.reserves import InputReserves -from antarest.study.storage.rawstudy.model.filesystem.root.input.solar.solar import InputSolar from antarest.study.storage.rawstudy.model.filesystem.root.input.st_storage.st_storage import InputSTStorage from antarest.study.storage.rawstudy.model.filesystem.root.input.thermal.thermal import InputThermal -from antarest.study.storage.rawstudy.model.filesystem.root.input.wind.wind import InputWind class Input(FolderNode): @@ -31,12 +29,12 @@ def build(self) -> TREE: "bindingconstraints": BindingConstraints(self.context, config.next_file("bindingconstraints")), "hydro": InputHydro(self.context, config.next_file("hydro")), "links": InputLink(self.context, config.next_file("links")), - "load": InputLoad(self.context, config.next_file("load")), + "load": InputPreproSeries(self.context, config.next_file("load"), "load_"), "misc-gen": InputMiscGen(self.context, config.next_file("misc-gen")), "reserves": InputReserves(self.context, config.next_file("reserves")), - "solar": InputSolar(self.context, config.next_file("solar")), + "solar": InputPreproSeries(self.context, config.next_file("solar"), "solar_"), "thermal": InputThermal(self.context, config.next_file("thermal")), - "wind": InputWind(self.context, config.next_file("wind")), + "wind": InputPreproSeries(self.context, config.next_file("wind"), "wind_"), } has_renewables = config.version >= 810 and EnrModelling(config.enr_modelling) == EnrModelling.CLUSTERS diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/link/area/capacities/capacities.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/link/area/capacities/capacities.py index db07796678..ea4dd677c8 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/link/area/capacities/capacities.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/link/area/capacities/capacities.py @@ -12,7 +12,7 @@ def __init__( config: FileStudyTreeConfig, area: str, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area def build(self) -> TREE: diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/load/load.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/load/load.py deleted file mode 100644 index 64aa92080b..0000000000 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/load/load.py +++ /dev/null @@ -1,46 +0,0 @@ -from antarest.study.storage.rawstudy.model.filesystem.common.area_matrix_list import AreaMatrixList -from antarest.study.storage.rawstudy.model.filesystem.common.prepro import InputPrepro -from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode -from antarest.study.storage.rawstudy.model.filesystem.inode import TREE -from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import default_scenario_hourly - - -class InputLoad(FolderNode): - """ - Represents a folder structure, which contains a "prepro" and a time series structure. - - Example of tree structure: - - .. code-block:: text - - input/load/ - ├── prepro - │ ├── correlation.ini - │ ├── store_in - │ │ ├── conversion.txt - │ │ ├── data.txt - │ │ ├── k.txt - │ │ ├── settings.ini - │ │ └── translation.txt - │ └── store_out - │ ├── conversion.txt - │ ├── data.txt - │ ├── k.txt - │ ├── settings.ini - │ └── translation.txt - └── series - ├── load_store_in.txt - └── load_store_out.txt - """ - - def build(self) -> TREE: - children: TREE = { - "prepro": InputPrepro(self.context, self.config.next_file("prepro")), - "series": AreaMatrixList( - self.context, - self.config.next_file("series"), - prefix="load_", - additional_matrix_params={"default_empty": default_scenario_hourly}, - ), - } - return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/renewables/clusters.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/renewables/clusters.py index 23592eb764..8866a46551 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/renewables/clusters.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/renewables/clusters.py @@ -31,7 +31,7 @@ def __init__( config: FileStudyTreeConfig, area: str, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area def build(self) -> TREE: diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/solar/__init__.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/solar/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/solar/solar.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/solar/solar.py deleted file mode 100644 index 057118b2b3..0000000000 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/solar/solar.py +++ /dev/null @@ -1,46 +0,0 @@ -from antarest.study.storage.rawstudy.model.filesystem.common.area_matrix_list import AreaMatrixList -from antarest.study.storage.rawstudy.model.filesystem.common.prepro import InputPrepro -from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode -from antarest.study.storage.rawstudy.model.filesystem.inode import TREE -from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import default_scenario_hourly - - -class InputSolar(FolderNode): - """ - Represents a folder structure, which contains a "prepro" and a time series structure. - - Example of tree structure: - - .. code-block:: text - - input/solar/ - ├── prepro - │ ├── correlation.ini - │ ├── store_in - │ │ ├── conversion.txt - │ │ ├── data.txt - │ │ ├── k.txt - │ │ ├── settings.ini - │ │ └── translation.txt - │ └── store_out - │ ├── conversion.txt - │ ├── data.txt - │ ├── k.txt - │ ├── settings.ini - │ └── translation.txt - └── series - ├── solar_store_in.txt - └── solar_store_out.txt - """ - - def build(self) -> TREE: - children: TREE = { - "prepro": InputPrepro(self.context, self.config.next_file("prepro")), - "series": AreaMatrixList( - self.context, - self.config.next_file("series"), - prefix="solar_", - additional_matrix_params={"default_empty": default_scenario_hourly}, - ), - } - return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/cluster/area/area.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/cluster/area/area.py index 233418aa05..2fed32670c 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/cluster/area/area.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/cluster/area/area.py @@ -14,7 +14,7 @@ def __init__( config: FileStudyTreeConfig, area: str, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area def build(self) -> TREE: diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/prepro/area/area.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/prepro/area/area.py index 8bb88d01ac..afc70243ce 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/prepro/area/area.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/prepro/area/area.py @@ -14,7 +14,7 @@ def __init__( config: FileStudyTreeConfig, area: str, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area def build(self) -> TREE: diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/series/area/area.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/series/area/area.py index 31efc9a0b5..db10297818 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/series/area/area.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/input/thermal/series/area/area.py @@ -14,7 +14,7 @@ def __init__( config: FileStudyTreeConfig, area: str, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area def build(self) -> TREE: diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/wind/__init__.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/wind/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/input/wind/wind.py b/antarest/study/storage/rawstudy/model/filesystem/root/input/wind/wind.py deleted file mode 100644 index 1727e37523..0000000000 --- a/antarest/study/storage/rawstudy/model/filesystem/root/input/wind/wind.py +++ /dev/null @@ -1,46 +0,0 @@ -from antarest.study.storage.rawstudy.model.filesystem.common.area_matrix_list import AreaMatrixList -from antarest.study.storage.rawstudy.model.filesystem.common.prepro import InputPrepro -from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode -from antarest.study.storage.rawstudy.model.filesystem.inode import TREE -from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import default_scenario_hourly - - -class InputWind(FolderNode): - """ - Represents a folder structure, which contains a "prepro" and a time series structure. - - Example of tree structure: - - .. code-block:: text - - input/wind/ - ├── prepro - │ ├── correlation.ini - │ ├── store_in - │ │ ├── conversion.txt - │ │ ├── data.txt - │ │ ├── k.txt - │ │ ├── settings.ini - │ │ └── translation.txt - │ └── store_out - │ ├── conversion.txt - │ ├── data.txt - │ ├── k.txt - │ ├── settings.ini - │ └── translation.txt - └── series - ├── wind_store_in.txt - └── wind_store_out.txt - """ - - def build(self) -> TREE: - children: TREE = { - "prepro": InputPrepro(self.context, self.config.next_file("prepro")), - "series": AreaMatrixList( - self.context, - self.config.next_file("series"), - prefix="wind_", - additional_matrix_params={"default_empty": default_scenario_hourly}, - ), - } - return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/area.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/area.py index dc5726554d..9aea14533e 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/area.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/area.py @@ -12,76 +12,22 @@ def __init__( context: ContextServer, config: FileStudyTreeConfig, area: str, - mc_all: bool = True, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area - self.mc_all = mc_all def build(self) -> TREE: children: TREE = {} - - # filters = self.config.get_filters_synthesis(self.area) - # todo get the config related to this output (now this may fail if input has changed since the launch) - freq: MatrixFrequency for freq in MatrixFrequency: - if self.mc_all: - children[f"id-{freq}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"id-{freq}.txt"), - freq, - self.area, - ) - - children[f"values-{freq}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"values-{freq}.txt"), - freq, - self.area, - ) - - # has_thermal_clusters = len(self.config.get_thermal_ids(self.area)) > 0 - # todo get the config related to this output (now this may fail if input has changed since the launch) - has_thermal_clusters = True - - if has_thermal_clusters: - children[f"details-{freq}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"details-{freq}.txt"), - freq, - self.area, - ) - - # has_enr_clusters = self.config.enr_modelling == EnrModelling.CLUSTERS.value and - # len(self.config.get_renewable_ids(self.area)) > 0 - # todo get the config related to this output (now this may fail if input has changed since the launch) - has_enr_clusters = True - - if has_enr_clusters: - children[f"details-res-{freq}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"details-res-{freq}.txt"), - freq, - self.area, - ) - - # add condition len(self.config.get_short_term_storage_names(self.area)) > 0 to - # has_short_term_storage boolean - # todo get the config related to this output (now this may fail if input has changed since the launch) - - has_short_term_storage = self.config.version >= 860 - if has_short_term_storage: - children[f"details-STstorage-{freq}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"details-STstorage-{freq}.txt"), - freq, - self.area, - ) - - return { - child: children[child] - for child in children - # this takes way too long in zip mode... see above todo to prevent needing this - # if cast(AreaOutputSeriesMatrix, children[child]).file_exists() - } + for output_type in ["id", "values", "details", "details-res", "details-STstorage"]: + file_name = f"{output_type}-{freq}.txt" + if (self.config.path / file_name).exists(): + children[f"{output_type}-{freq}"] = AreaOutputSeriesMatrix( + self.context, + self.config.next_file(file_name), + freq, + self.area, + ) + + return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/areas.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/areas.py index ac35597dfa..880a313dd8 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/areas.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/areas.py @@ -15,27 +15,20 @@ def __init__( self, context: ContextServer, config: FileStudyTreeConfig, - mc_all: bool = True, ) -> None: super().__init__(context, config) - self.mc_all = mc_all def build(self) -> TREE: - children: TREE = { - a: Area( - self.context, - self.config.next_file(a), - area=a, - mc_all=self.mc_all, - ) - for a in self.config.area_names() - } + areas = set() + sets = set() + for file in self.config.path.iterdir(): + name = file.stem + if "@" in name: + sets.add(name) + else: + areas.add(name) + children: TREE = {a: Area(self.context, self.config.next_file(a), area=a) for a in areas} - for s in self.config.set_names(): - children[f"@ {s}"] = Set( - self.context, - self.config.next_file(f"@ {s}"), - set=s, - mc_all=self.mc_all, - ) + for s in sets: + children[s] = Set(self.context, self.config.next_file(s), set=s) return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/binding_const.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/binding_const.py index ec1a3e2f63..822c5c8d93 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/binding_const.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/binding_const.py @@ -8,21 +8,13 @@ class OutputSimulationBindingConstraintItem(FolderNode): def build(self) -> TREE: - # filters = self.config.get_filters_synthesis(self.area, self.link) - # todo get the config related to this output (now this may fail if input has changed since the launch) - - freq: MatrixFrequency + existing_files = [d.stem.replace("binding-constraints-", "") for d in self.config.path.iterdir()] children: TREE = { f"binding-constraints-{freq}": BindingConstraintOutputSeriesMatrix( self.context, self.config.next_file(f"binding-constraints-{freq}.txt"), - freq, + MatrixFrequency(freq), ) - for freq in MatrixFrequency - } - return { - child: children[child] - for child in children - # this takes way too long... see above todo to prevent needing this - # if cast(LinkOutputSeriesMatrix, children[child]).file_exists() + for freq in existing_files } + return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/link.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/link.py index 5fc82dc57f..7b1fdd3eb1 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/link.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/link.py @@ -13,40 +13,24 @@ def __init__( config: FileStudyTreeConfig, area: str, link: str, - mc_all: bool = True, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.area = area self.link = link - self.mc_all = mc_all def build(self) -> TREE: children: TREE = {} - - # filters = self.config.get_filters_synthesis(self.area, self.link) - # todo get the config related to this output (now this may fail if input has changed since the launch) - freq: MatrixFrequency for freq in MatrixFrequency: - children[f"values-{freq}"] = LinkOutputSeriesMatrix( - self.context, - self.config.next_file(f"values-{freq}.txt"), - freq, - self.area, - self.link, - ) - if self.mc_all: - children[f"id-{freq}"] = LinkOutputSeriesMatrix( - self.context, - self.config.next_file(f"id-{freq}.txt"), - freq, - self.area, - self.link, - ) + for output_type in ["id", "values"]: + file_name = f"{output_type}-{freq}.txt" + if (self.config.path / file_name).exists(): + children[f"{output_type}-{freq}"] = LinkOutputSeriesMatrix( + self.context, + self.config.next_file(file_name), + freq, + self.area, + self.link, + ) - return { - child: children[child] - for child in children - # this takes way too long... see above todo to prevent needing this - # if cast(LinkOutputSeriesMatrix, children[child]).file_exists() - } + return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/links.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/links.py index 57cc0af3e9..1a74e89241 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/links.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/links.py @@ -1,3 +1,5 @@ +import typing as t + from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode @@ -12,23 +14,19 @@ def __init__( self, context: ContextServer, config: FileStudyTreeConfig, - area: str, - mc_all: bool, + area_from: str, + link_names: t.List[str], ): - FolderNode.__init__(self, context, config) - self.area = area - self.mc_all = mc_all + super().__init__(context, config) + self.area_from = area_from + self.link_names = link_names def build(self) -> TREE: children: TREE = {} - for link in self.config.get_links(self.area): - name = f"{self.area} - {link}" + for link_name in self.link_names: + link = link_name.split(" - ")[1] children[link] = OutputSimulationLinkItem( - self.context, - self.config.next_file(name), - self.area, - link, - mc_all=self.mc_all, + self.context, self.config.next_file(link_name), self.area_from, link ) return children @@ -38,15 +36,16 @@ def __init__( self, context: ContextServer, config: FileStudyTreeConfig, - mc_all: bool = True, ): super().__init__(context, config) - self.mc_all = mc_all def build(self) -> TREE: children: TREE = {} - - for area in self.config.area_names(): - children[area] = _OutputSimulationModeMcAllLinksBis(self.context, self.config, area, self.mc_all) + links = [d.stem for d in self.config.path.iterdir()] + areas: t.Dict[str, t.List[str]] = {} + for link in links: + areas.setdefault(link.split(" - ")[0], []).append(link) + for area_from, link_names in areas.items(): + children[area_from] = _OutputSimulationModeMcAllLinksBis(self.context, self.config, area_from, link_names) return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/set.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/set.py index 7b32fc5844..367edb8442 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/set.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/set.py @@ -12,38 +12,22 @@ def __init__( context: ContextServer, config: FileStudyTreeConfig, set: str, - mc_all: bool = True, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.set = set - self.mc_all = mc_all def build(self) -> TREE: children: TREE = {} - - # filters = self.config.get_filters_synthesis(self.set) - # todo get the config related to this output (now this may fail if input has changed since the launch) - freq: MatrixFrequency for freq in MatrixFrequency: - if self.mc_all: - children[f"id-{freq.value}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"id-{freq.value}.txt"), - freq, - self.set, - ) - - children[f"values-{freq.value}"] = AreaOutputSeriesMatrix( - self.context, - self.config.next_file(f"values-{freq.value}.txt"), - freq, - self.set, - ) + for output_type in ["id", "values"]: + file_name = f"{output_type}-{freq}.txt" + if (self.config.path / file_name).exists(): + children[f"{output_type}-{freq}"] = AreaOutputSeriesMatrix( + self.context, + self.config.next_file(file_name), + freq, + self.set, + ) - return { - child: children[child] - for child in children - # this takes way too long... see above todo to prevent needing this - # if cast(AreaOutputSeriesMatrix, children[child]).file_exists() - } + return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/mcall.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/utils.py similarity index 58% rename from antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/mcall.py rename to antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/utils.py index 212c40cf9d..c59a5b22b6 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/mcall.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/common/utils.py @@ -13,15 +13,20 @@ OutputSimulationModeMcAllGrid, ) +OUTPUT_MAPPING = { + "areas": OutputSimulationAreas, + "grid": OutputSimulationModeMcAllGrid, + "links": OutputSimulationLinks, + "binding_constraints": OutputSimulationBindingConstraintItem, +} -class OutputSimulationModeMcAll(FolderNode): + +class OutputSimulationModeCommon(FolderNode): def build(self) -> TREE: - children: TREE = { - "areas": OutputSimulationAreas(self.context, self.config.next_file("areas")), - "grid": OutputSimulationModeMcAllGrid(self.context, self.config.next_file("grid")), - "links": OutputSimulationLinks(self.context, self.config.next_file("links")), - "binding_constraints": OutputSimulationBindingConstraintItem( - self.context, self.config.next_file("binding_constraints") - ), - } + if not self.config.output_path: + return {} + children: TREE = {} + for key, simulation_class in OUTPUT_MAPPING.items(): + if (self.config.path / key).exists(): + children[key] = simulation_class(self.context, self.config.next_file(key)) return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/economy.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/economy.py index 15d648c205..c1a14e5527 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/economy.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/economy.py @@ -2,8 +2,8 @@ from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode from antarest.study.storage.rawstudy.model.filesystem.inode import TREE -from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.mcall.mcall import ( - OutputSimulationModeMcAll, +from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common.utils import ( + OutputSimulationModeCommon, ) from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.mcind.mcind import ( OutputSimulationModeMcInd, @@ -17,17 +17,16 @@ def __init__( config: FileStudyTreeConfig, simulation: Simulation, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.simulation = simulation def build(self) -> TREE: children: TREE = {} - if self.simulation.by_year: children["mc-ind"] = OutputSimulationModeMcInd( self.context, self.config.next_file("mc-ind"), self.simulation ) if self.simulation.synthesis: - children["mc-all"] = OutputSimulationModeMcAll(self.context, self.config.next_file("mc-all")) + children["mc-all"] = OutputSimulationModeCommon(self.context, self.config.next_file("mc-all")) return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/grid.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/grid.py index e52e0991c3..6778e09b7d 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/grid.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcall/grid.py @@ -5,10 +5,8 @@ class OutputSimulationModeMcAllGrid(FolderNode): def build(self) -> TREE: - children: TREE = { - "areas": RawFileNode(self.context, self.config.next_file("areas.txt")), - "digest": RawFileNode(self.context, self.config.next_file("digest.txt")), - "links": RawFileNode(self.context, self.config.next_file("links.txt")), - "thermal": RawFileNode(self.context, self.config.next_file("thermal.txt")), - } + files = [d.stem for d in self.config.path.iterdir()] + children: TREE = {} + for file in files: + children[file] = RawFileNode(self.context, self.config.next_file(f"{file}.txt")) return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/mcind.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/mcind.py index 8007eddd91..a69eaf5497 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/mcind.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/mcind.py @@ -2,8 +2,8 @@ from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode from antarest.study.storage.rawstudy.model.filesystem.inode import TREE -from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.mcind.scn import ( - OutputSimulationModeMcIndScn, +from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common.utils import ( + OutputSimulationModeCommon, ) @@ -14,14 +14,12 @@ def __init__( config: FileStudyTreeConfig, simulation: Simulation, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.simulation = simulation def build(self) -> TREE: children: TREE = { - str("{:05d}".format(scn)): OutputSimulationModeMcIndScn( - self.context, self.config.next_file("{:05d}".format(scn)) - ) + f"{scn:05d}": OutputSimulationModeCommon(self.context, self.config.next_file(f"{scn:05d}")) for scn in self.simulation.playlist or range(1, self.simulation.nbyears + 1) } return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/scn.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/scn.py deleted file mode 100644 index ec9caa989e..0000000000 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/mode/mcind/scn.py +++ /dev/null @@ -1,23 +0,0 @@ -from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode -from antarest.study.storage.rawstudy.model.filesystem.inode import TREE -from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common.areas import ( - OutputSimulationAreas, -) -from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common.binding_const import ( - OutputSimulationBindingConstraintItem, -) -from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common.links import ( - OutputSimulationLinks, -) - - -class OutputSimulationModeMcIndScn(FolderNode): - def build(self) -> TREE: - children: TREE = { - "areas": OutputSimulationAreas(self.context, self.config.next_file("areas"), mc_all=False), - "links": OutputSimulationLinks(self.context, self.config.next_file("links"), mc_all=False), - "binding_constraints": OutputSimulationBindingConstraintItem( - self.context, self.config.next_file("binding_constraints") - ), - } - return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/simulation.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/simulation.py index 1dfef19de5..629a8c937d 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/simulation.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/simulation.py @@ -1,6 +1,7 @@ from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig, Simulation from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode +from antarest.study.storage.rawstudy.model.filesystem.ini_file_node import IniFileNode from antarest.study.storage.rawstudy.model.filesystem.inode import TREE from antarest.study.storage.rawstudy.model.filesystem.raw_file_node import RawFileNode from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.about.about import OutputSimulationAbout @@ -26,7 +27,7 @@ def __init__( config: FileStudyTreeConfig, simulation: Simulation, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.simulation = simulation def build(self) -> TREE: @@ -39,16 +40,19 @@ def build(self) -> TREE: } if not self.simulation.error: - children["annualSystemCost"] = RawFileNode(self.context, self.config.next_file("annualSystemCost.txt")) - children["checkIntegrity"] = RawFileNode(self.context, self.config.next_file("checkIntegrity.txt")) - children["simulation-comments"] = RawFileNode( - self.context, self.config.next_file("simulation-comments.txt") - ) + for file in ["annualSystemCost", "checkIntegrity", "simulation-comments"]: + file_name = f"{file}.txt" + if (self.config.path / file_name).exists(): + children[file] = RawFileNode(self.context, self.config.next_file(file_name)) - if self.config.store_new_set: + file_name = "execution_info" + if (self.config.path / f"{file_name}.ini").exists(): + children[file_name] = IniFileNode(self.context, self.config.next_file(f"{file_name}.ini")) + + if (self.config.path / "ts-numbers").exists(): children["ts-numbers"] = OutputSimulationTsNumbers(self.context, self.config.next_file("ts-numbers")) - if self.config.archive_input_series: + if (self.config.path / "ts-generator").exists(): children["ts-generator"] = OutputSimulationTsGenerator( self.context, self.config.next_file("ts-generator") ) diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_generator/ts_generator.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_generator/ts_generator.py index 7721c001e2..8757debfd0 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_generator/ts_generator.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_generator/ts_generator.py @@ -56,17 +56,18 @@ def build(self) -> TREE: class OutputSimulationTsGenerator(FolderNode): def build(self) -> TREE: - children: TREE = { - "hydro": OutputSimulationTsGeneratorCustomMatrixList( + children: TREE = {} + for output_type in ["load", "solar", "wind"]: + if (self.config.path / output_type).exists(): + children[output_type] = OutputSimulationTsGeneratorSimpleMatrixList( + self.context, self.config.next_file(output_type) + ) + if (self.config.path / "hydro").exists(): + children["hydro"] = OutputSimulationTsGeneratorCustomMatrixList( self.context, self.config.next_file("hydro"), HydroMatrixList - ), - "load": OutputSimulationTsGeneratorSimpleMatrixList(self.context, self.config.next_file("load")), - "solar": OutputSimulationTsGeneratorSimpleMatrixList(self.context, self.config.next_file("solar")), - "wind": OutputSimulationTsGeneratorSimpleMatrixList(self.context, self.config.next_file("wind")), - "thermal": OutputSimulationTsGeneratorCustomMatrixList( - self.context, - self.config.next_file("thermal"), - ThermalMatrixList, - ), - } + ) + if (self.config.path / "thermal").exists(): + children["thermal"] = OutputSimulationTsGeneratorCustomMatrixList( + self.context, self.config.next_file("thermal"), ThermalMatrixList + ) return children diff --git a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_numbers/ts_numbers.py b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_numbers/ts_numbers.py index 2a74e256f9..cc458102ca 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_numbers/ts_numbers.py +++ b/antarest/study/storage/rawstudy/model/filesystem/root/output/simulation/ts_numbers/ts_numbers.py @@ -57,38 +57,23 @@ class OutputSimulationTsNumbers(FolderNode): """ def build(self) -> TREE: - children: TREE = { - "hydro": AreaMatrixList( - self.context, - self.config.next_file("hydro"), - matrix_class=TsNumbersVector, - ), - "load": AreaMatrixList( - self.context, - self.config.next_file("load"), - matrix_class=TsNumbersVector, - ), - "solar": AreaMatrixList( - self.context, - self.config.next_file("solar"), - matrix_class=TsNumbersVector, - ), - "wind": AreaMatrixList( - self.context, - self.config.next_file("wind"), - matrix_class=TsNumbersVector, - ), - "thermal": AreaMultipleMatrixList( + children: TREE = {} + for output_type in ["hydro", "load", "solar", "wind"]: + if (self.config.path / output_type).exists(): + children[output_type] = AreaMatrixList( + self.context, + self.config.next_file(output_type), + matrix_class=TsNumbersVector, + ) + if (self.config.path / "bindingconstraints").exists(): + children["bindingconstraints"] = BindingConstraintMatrixList( + self.context, self.config.next_file("bindingconstraints"), matrix_class=TsNumbersVector + ) + if (self.config.path / "thermal").exists(): + children["thermal"] = AreaMultipleMatrixList( self.context, self.config.next_file("thermal"), ThermalMatrixList, TsNumbersVector, - ), - } - if self.config.version >= 870: - children["bindingconstraints"] = BindingConstraintMatrixList( - self.context, - self.config.next_file("bindingconstraints"), - matrix_class=TsNumbersVector, ) return children diff --git a/examples/studies/STA-mini.zip b/examples/studies/STA-mini.zip index 1df2db61f89e25bf655dec86daa7be498837e1f1..0a4cd17045b6182ab5446cfeeacb0752507aba5f 100644 GIT binary patch literal 704805 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

Z7e(_S9u2gQZUuTe2ZFx$g|nd^OfaC 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̟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 p)rdLd>wGBQ_yF&( z;~gYBwa(evBA?>9%Ghb&SU1jw7kf{{FSVpJl^<#tNIdI>+~)h7N}y2DqonI}vU%jA zR)^(O4iTE}K@?YKE?F4qcJ&g)ye!Ig6kxMo(a z)PSoedZ0){j(y2zp;O)Y9VyUKVg&VN&InI+5VZu=BCE8O1FCvzD+eE)B@1D`ZTCP^ zDUjf3QH}N)%e81B+-i9-YlzNC!Lnn>9{O_nrHAaPjg!X`IU`j5%%CMJEqP58A+I?Kt5LuL0tZttJ*7NQ+q$={iZe>A@ok3%(E6zQcWsOP*Xu% zd4>EgdwR)NI69?F#s-hs$hG5oP3fa0R)_mxK852|Bv>h6bT2QEe#G!81%ANnjI!x@_Z0kw%Vp_!DlJSeoDa9N zy764G`YEocdLoP(O`#JMW1Mwij&wy)%!Z{zMAAf8h9keJiHQ!pQo!ZfvLfze;6bj?p%U8j1y5f1+)7@4@}vH9%jtm%Sxf+#E4+D?Gm z<`}lK*}L_63Z8IP9CBoM7=Dk=R$nSW9CT=O`SH;a9UzYs&_m6$O`IdXYN361#vsl0 z={$eHWq2hBb{o10X)7()zSK(<)&}gcbNEPWh5!qV;kz5V0cE->_;?m5cdETx@4@rD zKtW=5lpO2@OlE14DjttF;1GMQg|bv z5Tfltd^^`eLhkS+a9L0%RGh6{og@3?c3&IQ+1Gm3@cvA|>cxCKN9+Ca)A)jNfmA#S zrqNHAm;~K=a0okl@o$<`qh1jvhI_0i)w8!_6=eM)&XXt&oGK8ufy$0tRP9i=oJj?8Rtrr@{UXK^F)?^Ke>4R_oP zEG{x!Tz9ZeuZuHG=JOs{G|OHN_V%LENz__aan8HipM`nXpGZ3yi(wQyep2y4NQPmi zt;fbJyQGe935T%Te-U_Di6w}u`5l0wDdY}>#yyVKsC_zej#k8WvN-ke~}PB`Mz|a z;8ZF61xx6s`n6{t7$&sj32IM47%mkzN2HLKAz2it0#l-18zVhC-)T$S%X9USIz=&p z<&Xw!^Nm146pdaJM5lvyT<)m=xldiYRRWC(Ix)`bh_UgJ&C9yXQb)|@CGs*i@YEo| z&QsJH%u-2kFkAOEA?o8sUgkUIm_v{O-VRy|=2B82&PA(~tXAVt@klKLCZZ~TU48Es zlY?*!6ur`Kn)Dn<&@HOufhbh?j(JLd&qEyVgsiNq@yT;e7Cw8J@)C(_vJk!T(EB|m zkm!%A#9cMVAG24xy|9yW>-`F|20%`VRE}NbkmucH6B@2td??S{$u&+11!rywWqIQ5 zyPo9C)Lzrjb8e^+m<&@LJ?|10RnWuFA3F_45IP=Ea91gQyWOOMJ2AnYN=hZC4Kaue`~EFcy~e1Rz06T<><4+^1?1!d5ekIjF2H26+sZv{nKs6 zhP7gPHVeNvV!?rf@tJQF<-4faDvVjp{_Y*T#$J7!x`tGVmx!ZGNss|&m8T2~1jg29 zMNs3?3lJr+fv;KJS01&tr7&rM?)#)!hY7cr;wi=zg15QIMd8Tq&vEhWTt`%zEkEu{ zfS1Kyi+gJD@@7bQ3b;PrfO%2R)VU_;p#R2&b)U0ta`SQ{i+*u8cV%EG{kXV0U74=~ zi%g(fVZ=b|W=X~? z=ZVRI(Oe$}iX8(2o!cthxHXE;R z>Id5tL3+Yo*_2r=#Ac>FO|G}lxtJ-%G{nd}mVs~Uszi=lc>^6~)>I!UaPD65@|0;Q z#&XMDAF?_-aliIBJS|m?Zpf^e4$FE&bPko5lmjA10IRptI;}6AcZ6$a&n(rYB1-{Eg-P>G27tVd7+1o6i2+^RcX#bkbTnoyzMR8C3GlUTlg*|@&Avni~rm4Hh$GBlenAPV|v zN~T^k={1+pmX!?6AjSqQX6a3Ek&bfROZRx42d<=uo6?36uwn)x=0_x&@W3LaG$FDo z`##i-N?2FO*|ubsv7r=2a_dWjYk^%fvcUc$*=OJI^K<(2| zwmqk;JT$MLt?gEb;Q-q~aZS^9aA)=|Wtd%PR*>2VB-mjgdxRE?*)?TCX09$}U6-yj zQWg;M177oR8FtdPqB^=YDX-1Zvq)7ukT}}+u(gF{gKH$onL9v}ZF)BER6U%HvUfLg zG%a1G>MlxO123y|4zB(Yhch-Hx$r&4gOAY3AfBN*-gEKrO|C_42@Yp0CDG_Aec_lQ zOp5!C&2iaH8-jr9$Ngn;=R;8;UIs4DYp-mCbyycxEvl-il~*k@_(*hFZENPCNudJ} z7oM!{ojEjYY_K4FSXi>I?7rbdtChqKT%lW86@dGaC8yb_$%456e zf+;lu+{m^xs^K8%1f4p>X>K?Q_whfRn2kaj6{uaDdk2ll&)+nf+>s{8u;oitAdpxG zA!^FH;6;hM0!j)O&m2moqek1yF!~hgu`CB5`8B&ID=+j`*m2@w`{OBfhc1!DBIRnZ z!mlc89}h}N@rWT+7J@~KWlFtF4!jGd=oKq?N9kvOKlWhbj23d2S=VtQSlM3<-QC+~z2VHq?;rq-Zu{gF zd(2~Qw0cN3^JexG#G)d0IBjSVu*I`217Y)mSSraWE0Nlv%2QyaP2_n2aoG;=sHYh^ z?S#%5@a`S+)3I~#6)$K~j&-Z3jISP6Zf}ow?tQOpT^16m#-5wO_F1&;bZFfP3&h&a zbqw&dlU$gZiIvI@j2^hdqVXq($Lq?K4Xx>pepEul^mq|#n;rw#m(@FEDc)gZSnXL3{9i(^*A(a7C3_-uqFwl+9<~I)$@c|>JXKM4 zX%_j!*-EE2dmu{;OA%HmaBxqB#pnt0@v=b_l+PE{@31~jrpSstd*oWIapQRtPEuUv zon980x`&`XPSvT=a+6lszxU(=^ts(32%}jhx3VJI$$-zPUYKiO#KXhrtOfRxo`JQaW+f&_%&&@ z4)WF76`xr9o%4yl`Kx(7#d&B6Tf45RDf`)BEtVY`ba zUt#wc_>pX)Nu9HHqo0_pi>!s9ie|k$i7^!g;(|lE;vx?014#gCP--RoqD1`XVFT;+My8W!X4fjl?YucF)W%&vXv>e?N-wlfJ$ztkr=~>mA)61#{ zY4@4M*hEcsV|EC4_lDJzqD8M{N_WZLuJI_)Do5O8^`t1%+zq>;Kopyb{(DfQcPEe) zPg8IgJko%2L^g)KO)1d=MLC7p0G|VWf~q}8%~BJD{oY+%Ko5yZ2-{J?E6cp>xdAKM z0bG{`ExG$GTbecB*}8Accr?iAtkP*mj8~fY^C7KcYC86HDYzjmyWss4h3VvjJJ)+< zX)42wCA9G>2c%tH%I1l<> zsd?CZC_1iJzcJW%4@Kax=jH}y0e?E=ZJ`Me=J{*>ZKsh!LCjH|^WlS*EwnT|ac(!P zazYp9!i>^+hxuky>B42b2AbC{d^sm`!i-7X@>=pW^1-0#uhrGzQ+uh9b}#bZ!0lT! z!91)fw-=&Q8`P@b)!#XjJUcy0v=dZ#83#-|A3ZCBAE}$vZz$TiIDLq>|7bvU^em*`XHhAo;gqcl@oHm$k? zC2?$05GzThi>h_|PxkrBRUr$mcpzGF1IV(hiXRj|6~gN@p;U#nx>y5~P^m2Vu`D<= zwAOBUTf=+6;JB(s#fTv2jbhgp;bBe+2p%nSEhI8aQL(;ORk!#ld^Uk2z_+BKJwd5KkF`qPd=y z?E2@uIwl1JlMuT~h!J{IWKRNvWhMeDaWwA(^Uj{_HB;(298PV^(e)9k3!4?^_0D$L zO^5G0Y{{u^paZ~3i$4^QRc@PapW4sGL|+;@b<=Y6mI*8klL?7#M5oSW;_iSj)=513|K@%BkliTj=TlE*pDTAYd>~y-tIFeK8puGHmBT z?K*1u$gu`YsDG#bZmUH6eQ}g9Es9{=un>vH;T|zpz=h)id`lAC?W^;p5~FTf8E!4} zS@@O{#XMzsn!-{;resyuq<8lg&*3ku1vAu`rPfooxCVmuK zBW{WNFnmEOO)d+R4>E{m4$uxvS+RRO43ez7x~#~OABDRN@CHm>K9D5%j9jY-xF1Dp zDMe08;9vY)g)UVU_%qA*a2w1g06sr+`3K9N$)yze|15w09`~}yr}*O z73YVj<{Ezllp*yC0kx||$^QWd1OyEX1oZR=roW7#|AaHx6w-gl7;%y`KbadMBl0{R$aeVW(CIsy|C19|+Ic zpbdypDfu2IogI2y$OWb~`5jvnNDMXt)7zV!ruaeS0dTwc$)ld^+=+~0M{0W`48Wn{ zJucq%AfKfUobyb(06@cM1|)=mK~OyW{=*um2>NfAueY zq=l~T_f-Ce+0QDPuo9DemgYdL1u$R%xKO_`Tje46wOM{0Df<9 zfE)ngJCga@|35=~9=%`M9dFV1AhdP<2;>(~zVyQrFi)K%fN4B{O|q|0sysjd1MxrI z`v*&Z1Oh-YGq*M{F>w4>hWnkq`GWdL1#LkJfa(jlK4;J`t;z!xkZr$*YGd#_Sf6eF zn8&g2Vd?yOZ+(gA`#h3?eJ3IS%KyrvKeq?v=lm56xW46)9sK*K|1^(x-^0@V_l)%$ zdhD2!777AH1N>ill!o|DL;#fkl}F1y#Cll(YT$qIC=2<0)PI^sbg1uO8T>mz{UbaY z{{ZEG<*^fF*Zy>0+gB7mKp}8*1w;(KI49=xLCi!tMVB9CA|N3;hP-&+5BHrdq0}%zMW2G0Nwki z`9R-6+tTcpC%Vrb{Fzw%uL8Z}&HWyPhOx1k*1zVsUq<_)n0|zq5=;Q{W5D&fNdD5Q zJiy_<6VO*^+B)Bm_>+R+3uam_z3yLQM*ITiS7rJy$n^{6MPa|#Ut{6{#^zsk+*fhx zTK=6lHGpjV02Kd^y3+agT>%V)zu}69 z;RMO&SyvEH)v|q~6}3md$cllfuCbY&god@Xj-~0})XDeVIQe^S{5_3)-wi*Mzs1Ji z)5rJSzyU1e|1t~zJ3IYn)O_11zpsrfz@k_;#xIu$pp6#*fiQlfjf!7&!$ia0+{{kL z@@rWz?)`Ml{5gI6*aLaAUnJr`9(<*Uf5d~^-}c}uG5jMQq@({X2Vd#n7d`l##M_Cj z%t-(`CC7>SqB{^E^0Jb}A%?!Q~!f(tY-*@5Q_g(l(3IB)-aTveN!dFuG zM_k|q6i~m}5npNHH(UV7;6LjNmT$E1=~rE_1MDGN%4rze=vaN77Ct-i+4>Kb7hkH1 z?>k|E^@}`w?Zlt-@IO0o`FEW7lOq0SC)}R=4JQ7iiC=Ky^WHByF;ry);CG<_3(s$N ztst z;saJke>pP#trY;+KTc}Q&oTdTQsGE{9OwU-$-gDl;OAifIH^lN$Na}hl_mQzssCdR z|CZE>pM(A5q>_>UG{Ap=)NgMyrTjOhv4N@4uisDms|@q)QyWL$gZLZynx1WJiWRT} zd+7-NrxlbS#eb3aM<4){KP?%5VO{gN^!@}irIrl{4+i+px3YEs)%c&%*nhA9D=2dv zOKZT)_rKQN-?9is`yI@`k)XfNqS6mg{%IEP8NVOV{}qdmnZJYiH!||~Sv2_p%Aa-) zeo>2}(;PW}twm&x???21#UcggcQAi51%Do8pYz9;b@jI?*!>46--+zAvEQtQzJ3Pp zj`#d8FwHcy|6grq0%v3O#_@OTM52W(HIyxenX!y4QP){j5GWap4Q%yltM|JuI21-*B)Cu)-=2HVKqyWZ87F7F+1 zlUpnCy?3XpO=R!w)!nU;dc602SG(H0w`-56O_rGCME2eVuC{b}Z+uU;R^of_I#-*> z-rKa7TO;*&?-EzL+Pt@6@2E`{oLtf&CbIWVakZt(doQ`!t(ExR`=qN)Wbdui$E}fi zy!T#LyNKQkC-%VzrUkdbtxeQn{{)AeCkvyZz4oc+&|93fEisfuRulH?0-V#`$Tqj! z=5Et=J3!fHJF+&k@3PR965CGkJqa2XBDZrXxy0{gQ)~tAH06XlJGDuwnayT)W`1g1 zhOZ<;k>e7r%x`$8lWk~>(Z_Ebwt zAy&h$51n_hgt&zTuMh1R9YMvCCMxb>!Of1gce)zGn~F9A`z+htO=HYOX>Pgo37GxK z{*Wzj6}xDexXP1Jcn$4CcZ*oF(bk};H;i#@D&lk$`tU{<+Y-YByPASNe5E&fLy0k6 zKD@@=G`wW+R6)#k%5y4Y6S&w@VupSv+#KKwK}!HMQh zq@DOaT;Jzv6xoL#cekj=hpVN#HdUJsKjLCraaRla@DX=ox_o$gMs$ryJMn!uW~{4G zWFIbcx2VU5Pr4gM^kF#V_h&|sS#ocSP6n;@Cak@()x}b1rfA>YqCY3NPXVoV8yCHO z#a7kVpwQ~uTvpXrqtI&nc%HV3uS@Nfhw3mh;h<-ExYdHOzPxO2R`JyeT7igT!;l_V z|9HG%b#mv$$RS_0oE;G=pWi?tT?EXxWL(rQv_R$)F#-BP3d;CE#O8Vs1~@|5{L*+=GfanLC;PebMXnuVjGT5Cl`rKGXrMlLN`fCGfVA;O)_c2 zIA#aimRxj8fc(?5ZDWj%!2Y{J_Q|dAl2RbxE|$yS=A=G*)h*~bGm%Gy#Nsjq#2s$rl8AE>wT|)Sq$}I$&BAb%;QN9!%oxtcr-{#&Jd`1>*V?{ z?939diXl7%RQQcsR7I`wobj#^?pO?n|95*m}Hf zfD^DKkMn?Fulp*^;kOzlzVf#>!=nq5C z-+}~qeE`>eiSu}rKwtMQ5HX9PKAid8NG^rC_kT&N@uY`gXYza=2<&y=0RgKR!ozjn z{ZI3^8Bcc@b~Zf2!=Pi`*JOd1 z8^`DgxbFK#974V`>}QK`-B)+9n;zC_vE=b0T=z}lF{feOcTmVKMvudFpZ7TqnM>O( z-`Vz6H;jIZp68*^vF@w5M9eZq55P&+3_$|pqT$&)W7S!$j%U zBRubme^JmhMlZm1-y5O`c-;UeV1F*<(Slj`3G@Ja|*-lHV$Z@NnI?TfjP=?lA1sSjD4&ZQUoJJv->a zuro=}a+v<~rYdM-(Y8Ru&;ks{~kbS()hSBf0 zbv!EA)_olP?zH59(Qg>J{u+I=mAF}anPrR~fRnCo1qtx_0IvJ$yvd`4mUZ8KqNXu= z0j~Qhza`juyl#LKupV#ofMBotRtQ)P6JL4V*MB{KoAGpqA?V?Eco=l7`~DELjG;da zK?^sCwH>by;JR4nxbAEA zK7X6>bcbOl`2!vX9qYbrf|kSdr;}Qxb>D59#M+M62XNgt<3k<}P3ykD#f@Y11YGw` z-z=;EUT45u!i`%ZqOghg9Fu?QpY}x`Tw~V#$jz3OODJg$t}!R^m@8fDiLNmZ{oG&? zsWoB@_{{!3-h)DRi&YlQvQ*j*V|@HpG0QluhbyZqxA8D2tgP6s zhjWVuL`~zgAI>fOpYXI_Zb`#79qz2`60nNXYUuOpxAU}GenG*u9QynQFt2nKO zzFxG0r`7VaShnTR*DwA;%rZ{v;r#Io7lYFLkrm*2;PGi+@(2Ko<7fb} z(AVeg<7qecRO*a?Rh(8sU*G>NPpfrIrF!ibvy9VvIF)Mi9S;MT&8Q4;a4PkzxN#f} z;8g0718y1!-gvj~&A?r$qdewHr!*>R!;|;^2RWKqY8OXn_^5R_#6wUvp;2i&T(v9_ zw2aewIF*|5Jx}YkOr=hXn#O5A99|Cmz|(&0sZ@`{{8n*V4Sl}Fk39CvCNy|H|D>R0 zoYups)Lln-T8}=JIxJ!qr`^!kxBbM^ZtSU4o1^?zaas+1{j#5V?CY3H-7RPtr}c0u zmGKKt>orZKc8MFu(Ev`R-v8B21Jp~TS0CdrS30Fp39WD{^{|j#9HHT(=0DEUavf8t zy@Hl;S`VjEANQEs zfAO?l(^RVZ-@?XmG`Ng8XAFAIhGWpG+uU!mpa=B!cP!Qi7H&Bc*3ggzwuJn(l@ii8 zuA5UsPjC2UNHQ@>s_7W)j#t238r_h>8y4+5ZSZQ_)U#0=C~()z%4=a?PRBm50dtS5 zExdOk!S~;0|Krxmu=|S~J!*gFF8lh7fO*o@rt%w+pbMp*b895l3z68FX2AT;)vm(( zkfM9<$n#N~EO5NCbIWlW5n367P9jM(v^C=cd@HoZQffiCTf!fHnH5j zccQB;UEW)xoLejLy?2hQO=RyaU*4^edc1eKt6fCzg%kU85lj~^Q@B?Umg~}$gq2JW zr=Ei=IBQ#CDD;+~G#^N9pg+cu#1z@)HV&KWFHwZ;ys@HtJJnyI2yMQ>VN?ADikE;D zVarNPJF~n~O5ZL>?~tZ1o{;X+bM$p--@W8b=}Nks#!(xOx8UwyKSSgkw4ZZ-E(dy5>b zwvTUDYPIq2Tvk(w)w6F^Z83&etv1+hb=K7!R+AX33;C>mN344G9-G~oSY15QZZ)N) zyVbVw?c0~O^*++CE(==fCj+N{HQe$S`X}`KN=b~>oWg?K!h+&B`N`}F=`Nm6e~o$# z{nPq110FfV;n#t~_)>G?#`?0da*B;or^$%^xKTrPqiiZt(6gT3s5gZ)IgY%KGA_TM zFl|a1L_u^2Izmv0zUfVFs7-(_A>VFH%L8WXj^VmSXt^Dt_-(2MlM6(iBTEu%yy^~U zK9{FS&B@O8`3v$(2Q%77v=dxHA_Z!6f2UcOl7Ct^Odjv`((+_w`o}{WmxsXWth{^H zKHHp-B#d(uz8S2B#ApqtjpbL4vSyxBhbTHMkxg);)v zj@o(GT@A+)S#rZVs_6~V(u5u<8Je`=AKl!TkaQ$pSUjb{jr=rzf1x*P@D%c@;Oy=> z`31m#IX&jD14(n65s2mF3vY0K%ny<})|WcIkH5f|k(XI8MFfLb4GVSfyr8ffw;m+Y z`g5}RL!6Uw_HJR&^MknY?9@1KR>@1LIo#8Up$qfG1U*AN!UB{qgraO&z<2QoCz2Zh z$rp+w)}}m%ELK1p)1%@cGS(S2E0Sbv1}0$Mc9WVc1SZW_;LXg+k4q!}74lk(ZrO&G zt;kJ0qgHvt7zF4V_duh|&hZzFmE-&7i@4VY5%rcFE#9hV)TJo9N9d^eH&pyv^s1zf5!+SCve9 z0o;yTvEU@Ma}OPt_gBNSPDBJk$APOBcO!E`htTnaI*fAY=>6W3F3zE2>_BCyEINs< zv_e}!;g@{}6ZOJF$8i!-O0&^RmQxX?{nmgC#v{^|Dxu@ER!e_y4jp@kV1OxT)@sgy zFAq9~jzvS2(Nsgntp8r^>>N7kjKqSI(9S({jJ`t+&pM9c2p#S)`xIfU(*;QwcBv5b z3>z)044J2w+&19=u|h)5r{e>3%@Rw#J;31eg&K(TZa{@!ch3Br1gX7Y%ghJvRFWnw zGs7pho;p}=N8?6Bpr&CW9T}s9B)un)a-qw{nM9;Z$%LjC=(cCPNRf zdijnc9Fhk+Y|8@raLaTVRVYI|`6MX$@J-AU9`wAVNTR-j!0!G9Jxwyylqu$s*hi>X z_s)i-+=H=}OwWcf5(UiVSV-2S+Z)=I6N!q}0DI33@$1Hrp{zzHJLEN)NV-{&V{;1g zjy4A$LWY!gz-RmJI7|xGI7FKtA47%|_dqLd=ls$2Yv*V) z=5ZuQo$nV|+fv0q~Fi0(dE4mWYc z%56Kzapv4B4Pz9;MHWh^T&Nui1-y0-hJd1*C6<7@7o^1Oauo1YR4$DIw)hr9K+(M& zOTcV%^>Jqb*PwDq3uuA9u{G-pFBv;b^6dm3mDY#21`>kGAyMRK_&O) z*vig9&zj%3lp zg~D>qd0kq)QG?hfePKYScv^vix$sXFnZ|d8G%`#433)}BL;w_)Z3-+*f&dCj%1L=$ zn8X1N7V4gMuT278dtQnqE62;6FiJQre5p$AA2Nc3Ak=*pqEz`)8b#e@A<7bY6m^e< zC>>8ptD^3(FwA}-g+j6}ym@6uFA^RL!)&k9GJ+ISsJkp=IjF#*?z50(@?Y}0s5>oW zsr9!!i@MjcbH<=&g%nH489cY&I)!`oK@NHvpOMkT;$V;FBxVPFn2{%7E>=ac%EN)f zI0-Cxch+-OQK7PzGpT~z3iLXv3|3ZFO_i)SAe;SXirXmwT(G%jYyhs&GQ;2_08BAA*Pp_^jnT8NwrG_e$rV#&{GMJ7K zKk#Bzxip0MQ_4`9Li~c7s%l||czE=B(!E&(1yPR5qo|)^L6m!HORFM&h((Lp(H%zX(}LOc40`HZ8XcuQErynnlarP*#aDc0 zMXT9yltZ(dWlI$WJ$H+kwbvpGUAN*asz)){f@thb(t!Dw3IhVO{@X^Irny z)0YYKhFzAhTVNE4+Hxt1MkQj4qCtsTU9NxxQ=kPTdZzySuf!4b8_AbV)eM+BRCuhy zXaXeP?yjf6XA(e9!&t{!0}d#yAupr9<4JI>H_8q^#xEO6i5>QdFI=q*=Ypge)5Gb zoZUbGB+_+L0TKdG8gIG*Nk%mkAc=P2l+sW$9HC}ZyQ%%3Czl+L4mS*T@)R(S$l0T(LUokf<|lE^#|fT znSg_)pxflV9ot?ODiXl_ zEvrfEB(j{ik97KQ(CMjOG|ZBDyL_L|&8uAds>?_bg_rD<-BPhB<-5G%<}vNN5G`X! zmqRTpOva`Z?{TMj28=yFO~Ij**s=(`z36A>*fV}A8kF@=%ll!^R!?wR09aG#Btw{dAR?mIr9DB|_f`+Lad%B#PV_fYRdv-sHO)1~y84J7Z z?dlkN7Cw(nDcPDVYr$q ze^`}LeYb+mk_mbqL?RO1v#=cR(=*GDog$Zb%tXT&4QAIhf5g$sB17#~DB`MPIH;nV zES88BnpOGAS;VB{xMUhd+F%JVrubyu!i>CiRI@r7W=S-W@AJr8N5^YmQ_6RFDb-I!c(0Lu75x@TO~6BV6RI zqYcPpsND*;jz-MK5fOju=rA&wMiI^Da74u4I=bk2TryM<+cEpCq;T#s0aT{S8}DQ5 zG);k}dmFqgN5E9}7r57PbCrj`rIr2Z7v|s1Q{rHf^-*ZrELTy5$=64r`9z6^N!drC z@x7v=4U@IcLF44VFn!)wAxBeIOYBep%X+_~4ii>VPV&iu*~Vkm zD68a98d?$!RvfRgRvpcutehkpEc3kvfejXxlf;6(dHXtb$-+y^NuseYF$|bN1Tk9=ajX|P z>|gPgGK`+EzYzf}yp||O2Rf~qVAxN4TU|3ebrm#Qa9d*TYg#8N$ zTpGguiyPGC(iHY@*{F`DFYN!NNGEZk8aeFey{je_fzcE8>;6w2OjFo@9|28Q*w1`V zT{aD2zsCFOSenBA8whAR!v4q))Fsmp_Aek{X$t$xHmNJ7FYFKeP>oLFnnmQW|G7Gh zp0HoASy?4rn>-D+sH5o$`&$s$G=%-kkJKg86!vRre1*oOzat0d{l-XtKoRl)8x1l_SVlMjtseEO|8_^%?;z7bi-&0c28%08daIL@!qrvafz*`X6A;D!mf?koI*D} zqg0NjfBnLPUy*vzWuG>TO;WG;FGrj05<12w#U-?F7f;_};G0~K=Z(uLEXXY^$S=-5 z^Dmx|o=3j)&%((U88H>QWNgk1{bxYmm~xkuzl=1uit(fOtKp-zKDwz6u^&sm-5KLW zruT1QW1<10QlyBBJ=9%!aQXa>SY{fYR6YL3?{N{ zCtui8pVSpbDag$B4KDB&WabxSrsj)0-^98RI~_(lHrxk2uU;vPV}Dmj$ZfJ_Pe>n2 zB43oyTN-R~v)&>FsSWyN%QP05E$S)5gz_LoB(kWeROGP=ec0;=Mdp5Ws<79oP_L$@ zIOOV4p<2UB$UmiDDA%O=%5uS4n*z_;%J~fnza#aq`jXn+>|tz?*|32!mBR~71kkEH z{_CZKh*)$g00nz0Rv8Vx)`WwKK!iPl?U^w@=$YO~m@3VeQkYRZ?cjLuoDkqeq?57; zK5zG%8F&^=DX8bgUPtV{)&lYG}%F}>9h4=ip+opI#PDtmcPsq zmn_uDolf<6hoJUqU>J9TM{#a*d?5*{y^Oj5>yfW}JxU7Q8L!tj3@>0k(-NPxBx^-p z+O0cc>L-vfGX8ox7{$_uDfB5atz|QfLUb0yF%zmY=8;=62{Zsr-iSCIgVjgc+iH7D0*`hAs-!M7!v^f zhwXHz>qL*_9PFM&(9@=aDt=k1egSW|ZTjjJjj897FPoiMWUj^ml3q$IxX`Qey(CP% zT+2Q;&Pqa&%2u{tAcE%X_-7&Ad8!vC+QXet(4-d>9X?6ykVB}Jk}rG5t;p=y8HLPV z!k4l-*#kuq%hfCU6|ED3XLee5E$ ze^(r>EHb5O&)3hMOv)#9)2?m@YdRO1kKcff3E!y1;dqvq4=hM}>fa{~Bk%2sHZhm? zM5naXp%B1an)1V2KaxJ*L4w{$FtqjEhmI*RhFNm{?4LH~YT}o)U>@|%ufIj-w3S2= zkh5^p#b-Yuavmje!qvm#?{G1dr?^el|GoMsQS(BIVcY?FzV<;asM3#;$DFaF-HV3t zWw5GE)TKXZA(elevU?7xbvbd<*DBhVWcSUeD0=E(Z9kN({ELShD}#B8N(B3mgOT>ETXLzxH@^n8uV6}H{;sXL=Ju8i&T@zPV|Ay`Zz zVFtrkWR8CvQ#+PXI&?d^Ap2H}py$#jaG){P{EseK_|q*U4*o>yXBPr#U(rbEw04#r zd7jyL>aU!q4da8Y<&24-32#25PiUtmh!06l&H|&uFY%QWh9s+iX+j(Ibr9ULnvj6W zWeu36oA@r#%Zdy!8M6k_6>SX?9a2Hx$0X|Dla2}&@QSWA9*84htZr-jp5^UrH3CaN zT&J4!{_KIdhOwwkMVr8hoiy@_KS`Frw~zRG-bvySgO7Xe_Eez zOjidzqrOn#U@Ax5{o6yy(+COuMxddNM``ADY4rxJ8b#irZm{ou44B^_&@dM?Dbsva zrm0`5E5zK>q)hazQ%R@#U#T-O*ELa?HX<-Fw>CMLs7Kqq8{R1zy;DV}vbs_fM#8y! zGLKro+@}s>^KA(~f=E+$DeI%|+7PMUZe=8O&xT0vs3WO6HVoS%_o%2uZm4)muF6Py zHVoT)5opw18!}D#T3sP^--b-}_Np_fJ2zz7fWV~g-Rz~^py!TnRCKZ`L4{UG9RBSz zjIaS9=-H3LV^yZ&KysQXvA5F#X7WA^i3n0y>LSIH7+3~_vF@U8vGBt4)+GUl0KoNV zfDUPll7#&M;n@9H62fFgNjTWQwZFrH3r}g31Z3~t1iKDkg);{PScPv{6{SHbPO5gk6_Vh7&2C&!D$*Y zM*W1Pp1vWYI=Q|wc!(!1nMi61G-7Rz)n7A>(l@Bt1h$=bw=j z(=}xLf(EE-$av-#ED1FX88`ik1*d7qIEe_o%Uv@vC#z|v3GkP&|pi%`Rmu@4PS(~$AVA6V+?7&6-a ziAASj$oLKoPScPv^AwhPm_r6U67ND%4&+xEWtF%j2MhLKC19>shfzN_gh(U)Qr1WP z*bpN9qmHD0Y6y`Q{H?5#_@Uu?+l?x=+DFiH{TUUcl1r*gf^G4=_2eG8m;*cZm3OIXvrG(0$#xE z`42~H?dD-3t^fy>gIu!=eY!F-1k8gn9AQ;_C<^^?4oMo_-)R=P!fwz`V$)>@;(L@gZUjKmmlm z4kXQOM$9iK-?rdkS;4LC^3Q4h^hCx6lO?Nwe|5?0X_+*~&VS z);j>}apeRWU1FU{v65tfrDI=^X0Wc^a9~)Y#+V)z4<*GIMon_hoXs%_n03p`NYl zrNx?E^M>=y2~rBF?A4p`=YV-j6*VLUonC+YPyYcjIF0gtnI`U?>NK z-tR5x;v5jl*GAxy=r}8c78HKjcQ8>bJRq2tDv+rJgwI+n{lPgPWL&O>q@Yu)IS0Nx z=ok>Lt)l>?8W3jv_iAV7fUvNhI+lc9?g3$616eTZ$ebe}xMK`#D2rho!$@MVll7oy zs{}?_@hc7l>p{=?bbNrW7h=hmtz{4}J6|QPL3u3|A6^bQw}xCDz}r$joH~gQfjia z2r#9fKgO|R*Sqa^Ye$e|*>6ZKY4!~f0dr(CA&S!a@f;FRHv4{YD@KB#C%!F*aps1a z%63R1u)I*vGLxpv(Q>Qv+5LRj`PJHqwY=Cqb5eyuu~>?NIh;bFh;J{W1#=#SLh+## z1#<+&LE-d7z$1;J9mKRKOEBgz@8p(jN$`NVMaI0kS3-zkNfH{UJ0*npMFv9MCn3bN zjuJ|!yCe*iHLe$fU{Zr6eG-Ps=~DL9of1-9(n&@Ib+3dJOQk5(-4arC=q#g!x?i$0 zxS(g7Acb|kU1bu%KAu5O=PqJ8SOgO13G7UwJ2R6Bn5*R>!tO^(KCf`QzF${qRU9tS zOCrGx_1_hc9PU6$GO_PY3Xsyg@-o3&kCHgB*IM2vj}v~+Q4)#G;SZSG6_9K<8zp&Q zkB#jnFA==UD2W4mtb#`#C;axJBog~hqJUYXfaG{zk%P)(t$?H>Oc(T$mqztyoKON=)J_{9a5lYF9zsu;PVXbFimotS=@xk;U19oV1ttw)x_e)Fi8O`j z!wN_`!t}kj%1fjnOgFeq9!FD{-l%}2FH9%*lM_nf^e*yjdY3$eo-m!)Us@GiVY>DJ zc_dw7dYuB3hA`cKpu9wy!t@CRBpqRT)*yL_G=%BqgXM8Fh3TydNSI+79wd$*A|_N> zS|-Pyi_<)s-E$$8ie=2JpV>f&tlK3tP(QMP5Eo=1)K6?6#GIiLN{AoW?2noq*mzh} zh_>13kb{GIkNttYjycH;dfvK|ha=55q0pN; zr7TdmJgH80VW7A=S;Q`z8zu&0s=n>)vaaoHGP5`AaI($9_8W;@4)m;5SdDsiFp>Gcmg$A#&+icAVh z{ax2r(K#-}<*87q#)YZNR-Si`3o(TVToQ`8$AxB-q{*!FI*!NBo#T0V4r@bNk^`n4 z)tM}zM_INU2ZQyzv)OX6)YeBg)gg`(OTKJQaKQYY3&!s+^kxm7l3(D*L!rwYdZO|_s&TXBa;IlQs$rl0Wn;ABPTQ6s4Ji91>7A`(6>u9IQ8+!?-FfV-I8=89=imO02_-pMW5Swz5mUBQgdExA571S`}Sk`lJGqt}s3KC3%@N zgz30t@;I8p^k)i4I>Pk0m*pkW5T+|Fm&ef*rk5!o=?l|+UXc?@;G%|mnEszUgq|>c z#|mjxbcN}E6_9j=>BTGMWzrC)uYXk@M^l*oMgd7jn4Y*wULp-)y7p`GIGV!rS_LG` zFbxk9Z+~4(sItsKjy)Hr0L^ZVlQ-STm{&iufe=GiOK6~eWCJ07mVr<|v4Id%*GMQK zc3?w&Vi(B@S-P$9P%A^}iqPdFx4tY`FiwsTIa!c z7uIHM1U-9!4PQY)ravRUILm1G@rRP>RT-D-GPDg7T73RbN0RP!XCuS7iuwJ3*?b+_ z2J833674wJV(G=Emo);mK3(r*E5qma<$1HxyanFYnf^=_=^8NRf}RHNI+-KAlT(0%pItj9Q@n(2Hi-WkDx9QG#!(x`TN?Sq9 yRE;r=YZ+4k^XexeH_vj%(#C!I@qNCC`H&S!Tp};4T z7=cDh$m}@~{R{CwMqtd^9G0;gVmY`MJ?fuPg~^vK5+!eolefa==dd(g0pB0|=~3SU z=ur|UeP;0TA@r^G(K`VHY&wl*O)y|QAto&?J}GWO2OvPi%(0`hW8e=<&1D^H1?G)d z4sXPPDNb+R8VsHT2A9M>P?Djukj&zf#;2zV6y?-d*2Ju#Zj}saCOnHoBMZJ-T_iny z`n)0CgqM@nTJUU`s#p`?@CpI41whV8vxdwM2IeC5*^c1ZifL9np9LCLh!ZIkz`!u4 z29`cx29RL0KCn!oRk?=`{?|NsP7{wX3Gwpit#ol3FpME&3zEQ}7=;2utYg9Xf+6yr zvD7W3&w}7dSIHfp2q59`I!@M-${1hozPar}g$=ip5J z!sN9-DV5#4!pft(m9hT z#m*$c^}{knNN5`ieaCX3YJf=Dh$8PjtBE`UO+y4%St`byK9bhRYe;8NXR#}xtA=zV z$$A1#B2kLYd;k{q>my6HB%SIBPHm}k*#!+^%iAzrx*P>ohH`PQN%vI&t0Z} z5Yf6|yA}5FuYBQ}py6Pu&t>o>(Mg~IkTATEe3?$d)4q;N+8%~O*^<*$g0Z?_dwaR# zG@!AJj!cW}kTy9DC06lil8n?)t1wcB(%C3dQ(+B8YVdrA+)Yw!Oj?M6ff@qvCO&;xmf~;8Kzb zz9<6$96oNvGhQptx|^htXWdQGXyi3eSVZ9A9MZ^_wjqV|ye%z;qw#ohthmvnu)jZ8 z@~pWL5s$k9?S;jM<3{TXu;3<%n7o?h6#NI;0*vEGxn@~v)R$r~nv+zDt-T2peOZx+ zTzkXkvG>1OguhEMUg6yqViuA~cX(N9$4BNRuacR&iKRF$q>#n(g?N&x>5Fj^L9W#} zPE?c4qPqJ6OHGnS6>In=V_hT?ump76Z!FoSDy)6p(%dE}A5!srcv2!{BX@$i92w`* zT-gzySg#`j>|;HP2>Mj4lN2H%<6Xw6atNY6e>f>Ljh5|^N90+yM;@`_oj6AXec5X$ zn22x^d15|6LMh}E3%k>r@-FNEg#r;Djz=lt<12O`1MGt?8-;t>Qp1<+1Pv3b)1#dD z@gfVKGEt8$+mlc^4+MQEbu6I;TZ8J}0)%{$MopoRFF>KZl1C=8;WVnRQ4uIy;eq+_ zHk{^QKYz=JOVWZqiNZ6TCp+X@sH2@R6zo`aHixQUVethr`{h8><2?kxK7V9UUC>7! zv7^c!tS3YsvBlnLQ?^Sy4%qTO9-&~5Xsd?!AE(2XSHl>f;b4ni%TTc(_23J6C@nojYFO6zAxl$6 zh2$NeswfQxrQsPvscI&1k`}x%$r{v0tVmU0cD#yI>5~INN}!Nub*AbbKq1NChpXPm zDl#=DQgCu4UP!|dypcxmGn#_S6wYWcvfOuBo^?Y;1+{WttvOp)$qkrPMun$jH`IO{ zkJ!c|MZsmT)4fD(yPwm64V?)mky3{sM<5DrV1(f7RI)eX-v#gwM<}|kD|-$^=?oBb zpj5CxBcQV0Wp~-=xP(rZb)*p73E7-3bHFsZvDIaQV?=s`Q*C{b*wDyG#)x}V_C!Qd z*3qN}@XE=jE5xyYY<#HSPggq2WS=Y+UADrGn^DR$0^@-c9L%RR1u2mQGce!3H>j0< zfRIQd{d+@4=0r%3)P5q5M}B%Or$>HzP1z&0pIGr~YUJ`roP@GRg2%Cb&Xg9^e3v9> znAi$%BrIOpTiL@91`bH%cT+%wnYy!O8#&>p@cDJ_ z@~n6X3Jx#vnp{&6YE+@-u5ci>7nP|Lf|DwJSbA_Y5EMBi_8=D0;h{Bn)-yVWO5+Ss z0(e8aJ8}!yQgc94CTQz~02sHJg?4q~H`EcGcMzqe)<;mQAt2#RZLcPA5noi$-cy;V ziV!@ujU_r)rB_9;ilgKRm|BT+rVMzCJb3>ymfuAl##&LX5B)1QW9-rqyd+0iZpOT2 zjx2fPhH*<+Dl&M)8)jjbF;FZ2|47|F2V#WBj*v(A6W8F0Rv>zydX?kL))zE9Nisc* zzLTY|)Czyz1mEFXf%eyS;#*+h5oHS>xc!6pCRm6MTN}y%lE9w`M?Ch=(Sq^~Bxo%t zA!MpFdK&NEg##3JCkJSa-7S+=DfRWX;1|Oi3#~mqr`Eg;zfhaAG@&6$H*QyjB|ylt z%{Y-RBMF_gknxI}pp6vvR|7Iz&|WUSdG}nr%d<|;I?!QvqNWmLFQpz!)G#3OsqA_zLnwCr8%_PWyTqzqaW&lz9<_K^dV8X6oImrxe zxO^*agPumX1sl4nzkGQb_^N7T0CH(nu+Yy5G*)Ciq-d7&9W521#HS|A1`|) z1T%#R;@AL7e#m0OtO>>JDn20NnYJPxUJC@t1q-QUY1l=_P|AHUqwz#Y^(p0O5fTmF z_;J)Sv?y7-*i=ePqMLVMkIM@UCAPRw8j_NKTdBF&ZZg~NOLz8z1aC}}zABvG3-|Hfp-QLX- zbArji$Aco00d{ks|%nQ zfB3>S;l&3uO9Uc>ZNhudgIWk8WsOCgVyTeJ7K*aIc1mGcbGs`jYxVB(%X*Pt^U9ja z##h9yh0`iUSqGk1Sk~S_3d;Igp!~893T#$cW1#7Wnqh+-Fi0gt^%F+w3z8#s>&vLB z9U5vYvC2?%q}N{tSviZjS@FSGHm)KmXzu=ns*bT~Zcfczs+v6BY{48uPA&v1D%A$Q`?r5``T* zSfs!$bnS8$^@9nW5&Dn%0~svcfwpU_vc%)3j{>bZFT08YRFPLKYapn)9G7tintZl#0) zkW?H9PM-IWgWAExP9;}uWFt|Pt)wKXlvSjtuwAQIQe<_BJyb+ijr55)+`y6|D}grg zD_!T~wU36*f#7B! zaw8Idt#(^pgq}fwGt3gC~*!x@=H^|JLbIwFMUd6nn>Cr3ea>Dny%Qb z0u)ZB7haH*e{#6XNZWqe(h))y3B~NZFOk2YRDy4H9<%=({ zNT3tq+y=|piC-lW-)3>%GzR5)yx47FYT8z~i)g6$%m`h3)?O6W0R^VEo7F<{lBU+m ziNB<2y!eK1=mH45GP4#k7tjI@g?or7ame$uRE$Ba*It%99Fphza4kZKLo9ZWf-=ND z04-1#BCp1hUxuN^p~-#)Ipld+$!3r!S7WCOSyWbN_)!>m*c?B6h60zcK*QrBe)tRs zY$=td`H!1piG?gSHTfduZG^3q8cU`;V;gn(*fO;P!z3n0i&O_Btc^H4zO+njge{aR zcjay6n(0JK4Do_B_)o6-U9b(DL7O&1mUB-qVUr@nRWYC6Hlndf1i-GT} zL7wBenMm2#M403WZJknv84FBP(lG;or{R4Oyp&-Uc8#h%lJqH{!g8+2W6)p_Im{oj zgmt^ZVsU|HATQGRp{1mW_8)2qzbG|1J&pew&b*KFM@f1OC!87W)v)ISwF4cU?T|Jm#$iHQdi0cz zsBKOOj`9eoxOZ%uZtyAiGX_7b<4~rtfq#Go*iCDI?X(8iPix>S6dY681U~gxk72?@ z+iWEomNJi{tBijsW5!Ki-g{!Dqk6#05%ao~uKilA>Hdo0{&sgerImBrboo!; z{He{Zj)B7uM0IxgQpGe<_GvJ4vdrN2vlwP_vW2((pFI(=o!g{#v|ar5&!4j=7B4W) z7@GA#?^r)CJ?x38VScJz)IrM`p+{nzKC|kdc+QR+_%6Ri(abhs);44A73~<&zkFW$?%G)=e);JSim_hjb?tG= zuydQfs9ZjuqFt)@WA5smJ?|zsGLBl8KhfUVu{(3_3r61Dznr+`Tw`cD1A=Yo&^x_^J$~qW)C~i#8&EJmrPyELIum78d z28Us9t2S+U<@I3T%q3GljnliY*Kk}jxM8Bxz0dh0E-kw9t&3lO2h&d`0nx>p17d@X zKAk&~rE@9Rxg<6|XIRT;BY!3JI{xhY&)w`N_j}x(*hk+jW&E|M3RP#LAtrmdwc*om z$K1I7f%m$q^GR;l?Y04V5l5?{Mpg{GJhjuJAKQ&g*D9YmJ-TnZ&3{{^9V)s0Juhr! zq~HGHsk=7Uyi&L5U6gXMXi2ESe;R8qtK`>fEG|p5w)heowqt4BCFdyXOx1edx|?nv zf30ofcGGM_d9e-exaluu_iw%5ZrZo?b~kMO3atgp628R+eVTi>*9q>`^A9(ERJQJr zUy*3)HYKjZh_Pj??A<$WTk3L7ub5SM@ZH6cUWVy^EMKMRDOq&1FD+8*Y!hGj-s|KD z<@8xBtHYjAt!B7?-J|?lIW@&2+MG3X*=A-$a2v;>zJ)REJV$L$v>MTE->(|pl-qS9 zKmKQAZDNeK%$Lpu}l84v-nw5O{^Q`I*72j6P zynpt2!OZDP_l~+5GQ6MFy|pKJ8;o);4C}b$@04**>yB4XJDK3wdyw6KCG#4(*!?;j zkes~!;Pa?~fAOLN-$Ayjcw8F;EPg!rK|d05SE^CFe~Nt8G|8 z+x`v@PZb;d2yh<1Aj55e2e03u&~nwV@Lhu=HY6L?r?r{1@=E>2S@y9EUFA!2U%gt- z@S%H;*fO@?rG2~Z)Y;qoTKCe$=EXx#A9m%7fvY;M{Cs%_XZfdq^bJnK<9d2^sy%S$ z(9`f~6OO5+6?I$QUHjF}Ypuc#9dY|@Z;`#GfTf&IyL#Nmv+YK1u@8$g<3E;O{ZA*G z@1J!0J$bq<|MtZ)pH&O~(nTj5Yd&VrdN9dOpcrK@JXu}tx~$Wj**->d%Zfhe{1-dS zOdoUXwK2b>!M-Fm|JcT$`tQT07`m&wIJUm#ud}m)v#LkT^-VU@GA4}AoHM>%2vd}NBfbtBebnpy&M?~jQHyQa>b-w`^H84R6&zH0x=Ub9iJ5l8xF;H-^O$CF zEW#Vi!G%eq!N`j%?YJsaom;gmeB2pFqj~$P|6BaH?(p3YZ||R5{i%y>(C`xu1NS@X zKT>Y^u_Sg^%IL@HgNL4RD`P)!_|WaQg8y({hDbXy}UsZPl>XA@=j4Z)E!I^d4crbxO^) z(XmZ^>^xX+U7On@wkVHWv3QWtHMN-=f=yKILykvpa6NjnTao4U>6RV6SZ+Nx>^vS9 zlsw-1)`4XgW*T7bpEg}qo|(OUncJo|BUc|j$mu_0bgv=Z*!NFoFK8Ij8(ZUjhqrFz z$-Gw&0$Q1+4X?{yFyy6oRY?AWJ8yMw-!VQs>UUM8>f!5}hwr>TmE+TTV>izM@n=75 zt*cn_u5_zfN_BPqQ|L7HeG4T6!$eF=Ncl#5uP9xB9j^t|Thy{_dV- z`asf_$~0O#zNFvxq-%1kax2Epanzf?FJ%3hHC17A-_f($9x}e@uXE^xe%N*(X--vT z*{VUemVS%fzeMNH-`~oe7ie|JH`DCgY1)|I@8A9Wd?Vk_%BgLng~5)2=6Z1-zp}Lb zGgDHgX#2d3TsCI7eeSAG>Zw+`wc|49Ua^XQwzo@U#KEHxcKVZIIv3QB5W*P2?d;0xw`GvTVu}4F6Rxo$meKugoz1`z8 zJXWpRa^PtsJEs4r#15~w<+gp#vHP_)?ZrxS7d4kh_0cr*zTN+xIPmV%s4tEk%C=by zetOp4HMa8Ww%R-2lK;k)r~N+rAUtr)n$DUJe@#!0);jIde&L@Zw>jIcoqTq8Qe7kY zjX85?XDbj|`f1Z>wuJo5u~HWXn_HLLCwsP|*8H-w`(DNDW9_Y&FmG|y^271kCvwLe zXgkw-X29Qu1N$us`@f0(arkQVe|}98G*!R%J_q8q8=5AN9;BH)g%=vZL2@YyG7QD|>9r4(xTP#pr8}*$Y?nx)%C+ z26tJQ-xSNw+S$4hjEh@?XKbE3_Tt*l_w^i%20L7d)3!2=?o`{!YH$yR%K)9-ANu#3 zh}nk!9OG=&VMvJi4V?vc-oxYk(nD|be-O|k)y`(a{tktE@MqQTwJ8oW{Ezf{ zG`RPb^@oD@9|^FoSvyGSP+{=$_8tR{zuL%r-u=dc2JWrgcawSszWl&#JL=8;JG*v# zy)yf%(UaqoO1xWVWsjZsq;HG6$DY68Tz#Ti+3O>K5cmK)WVPDH~FlI>b{1WFBvnt?(P$_bhX2;O_Ajvdvon}-e`HN zRQ>VUN%6N6>nDdh8Yy#^#@D>MnEq!|iSywMbJdIp^*g(rE=>QswBhwKR`%Sv=UguL zx@+yo_HEhgx3+ox@d>??JNN9B-y!_nsxFbP%SX1)T3-6-{u6KCUin$z&z9$F6sq*w ztgL$R@zrHI+eZ(XwzYd#)52^e+l-@y_Xe4_>34DO_uwA;=ii@Z+WpFs)Azhm90qJw zesllM`qw&1J?oCC*mhKHed%dd^zl1!-7fw|u0Dx0RWs01dmiw^M=aQ~i$^>=?z`pT z$+Mvgwm7xX^;ke;(u2f#i^F?W9$ff1cg)5`ewJe&oobzFZ?nn#^7}4*Z~Q*)HT~OK zt?7)*DZJ7)8Qt^NAO77!Eo!&TdgqOiy%<+A##b{gu9~Hk6;uE0cQ2ZDzVPuYe! z?haet(X)s9r7@-P{+VBuWBai8pX}}XAbfsW%%%skzaAaSn5ma`>_DO^`%b`7R*a$X zqNVxMFO=9kNxE=m4lV7k8U%&k5MrZsZK<2L8^oEcj!PJCDw_j2^(jUnAV_D5iQUGKfw$BAxp z%GrBQ?f%}i%SH^pcl}|T2OC_c3`_E8IAwOYOXj3ki3VLiX1RH0S6x2hSvn=<(Um)Y z?yfqsDzmCM<=xmng9lFA9ezFbqxQ+`J*rlEPn(*)W8Q z6(>)O`!q6IiEZK1I_RcV^d{@nc_X@A8CkR3VKh6)#6E ztu5I#mfq^v1gAX4#1&I3=S&^g!&_}L)-aSa*}TOX>+X(L8@anmZ+ELZ^V__7UJIWL zwbrx!47)J`I!sqzZ2Gf>XwF#Snr^cJ%#^>%AZNn*4NIp3)}@}`|wrIVc!@pKdzixaU&q~ zcu@ayufxn|F+*5!nkGJG#anX?Iz4|G4rkl?@kZM9`#TLf#Z|?u_%%!IM&@px-Y0{w z-9uY>)%(%08A%%5T*IqawBNnm+S2cB9(l@l;l2e+2))*2VUTH}JmwZ>VuGTVChxvjQqzU8cL`DW)7H(i@m1_|>gMqSXg z$hf+)bh7e{l{#mZ4p*hMSDO>K>OX`2>*o4y4LH}(b@ZjpJqOxPJj_zs^R-=`-vzMN z*b3Jg+T>cJzxuj1*F@GDda5bwCtn_!oVsO3Y{2Sz|B+L*QnR`Zno^cqRWovHjK$I! z_8ron^yIPsGYgHZ%Um%z{^8B`f!~(e4zIV4@Sf>ecPgyp(SJME*M0na$iM8*!CK$q z^M58!PXBYOUU_x+iEh5(>mo-Ut3Ht!QCSx;eBGZ`?5`Q$YgYxen&}#y9ez7DB>TIz z5zREMGJ=(MKXHzBIb3V_T&(J{lC}=~At&u&{G3UmX4B#8(FGz)4J7E3`b@ag2p@+p zHD=CpJ$8sy*`n*%u`XGQtjA8XJJ>I>{So~V?x}0LS10XuofE$NlRgXC>50$R0+p{vxkAd0F+17KRc~s__t8-{OS#$hXrRI!?i|jWhXZ)zq z*2~R;BHxVF1*95vO^wX**q~1P8E@tu#ww+H;PdaS!(oK#<8Wg$~a&VW}99#tun^> z! zEBl+R*{E`Mr*FM=)aH4aZP&)0yAl`?+iUi>aL$$Y&RbksFKv77`A+t^VNb?Ck9!-u zy~~xL_LY|clT@Bt-R+T6>~gWoKyTg(-Mw3~Swj|8jtzQHl*cx3U8uaa=&etpz3!GP zH}uLLzVfYK_B81?_h5A8b+enVe{Z;qwNLo=cA$IA=@|8t#~zQ(CjIW&*&}5e^Xm2K zDf6eKWPF=A!KQN6<#F#@Oc>hHb$^E&OTj9m{osq|Pd>(18TW)%8B_OFfmKG*{e8iS z$(ar%b7uDY0#+G&*WKAV-}v~POS?HrhFC zbY}gZR=;mqXq&Owi{f%u><)_1ncZpmcPpRIQ(oph9-Fn?C%ojLOX8U%n-c>~;QHY_ zclL50(_;@^Y<*irspSW<)w51u7Wk54!Fczm*3ABl38VMz^1;_4nGqU=KiuapH=MK2 z>uK25K=$pzU0%1^Jj%L1Nv;1#^=`{9nqHo~t898!eIpZ^x^>s@xx%Xq;DT_K;R{z8 z7t69kDz5Iex#n##4)$5{YK6aUA3dGWrzaaCqJ523f+kjudHnas2fKME4H*^7 zOkCL`bh<{rjz9Kyzxjp5Pi*b-wp!<#uzomdJ<#d{T}PfwOJ36{q*k# zwttf|^DWyjXW7_RTUSQD*S1IClJ?CNOJmh;zTBz#Gqn8Ol>_P40}Y>BE)S2k z?lSwc@!O3Hj~S2F-I;y)lFGfCJ?8GpuLef6DUbc4c%iaM(Sd><1{r=au?vTUAEeD% zo6UW2RwpK2vo`g2+>;$GFHC>1A~fffi^l62A3Qx;e=(TRGAu*oSlWrBgSmsu?dtXG z<24q9a~3>%=$`zd!{tB6FJDco{QP(N{YT}G3o7l$*O*S2Y<7&7G9}~7lOrp3HSBTG zh;yD;ec{lq`r(`0N531}h1t5ca?G=(pNh5)DYiK_v9ktq?Un!Z-s|t#_{hm7B-! z3G(Q+XlA=rcA(Oj;}@>7RVzX=GUHpJDH}v}pJJ<=cHv z9l0^TVkd_A)l4jXasF!fo4-HP*y^{AEO$;h z#HZJH+46@Wnog@3WtJ8|4{d2=y%}iM4Ab^dHo!`!F*QVL(@}psk52^3)78N(0asqf z=}a~5`Q@XM<~XV^*l=sW_>9DPf4t9UX>FUOs_)Py;9KHp(ghy3W6y4fqWhO6(r+zT7ADAi@gn!+O!l!h%HlK(pZ>$Y>U z#;ORl`MUFG6?BQQ4}QDd%xt0kg{Q6qyGN&3hqqjPx5AJcIPpTtO4g%gL-bdsC%JXW zGOHcX!OPvX{@2OJ3!?t`J^rw$(&^?NSCF)AhexZD1N5FDDHbzayI1$Q_2Y2nUgNiZ?`O_Gw&8_Y!n?`# zSGO-PeiONR>OqV7u8f)7b6dVXRd49p$NRz6JsZaixVQCh)fw-#7rx$1P}%+5Afit( z?QMz5(6bJutCQ$=Q`Gj)A3m#d6=U}YgOISKPn%yGgp`1P)Eb1W2LE_!5YiI=!(U0h z6{%{Aw+`=@RyBKLt$|*j;`~=fR07UA*sKPBHR&oDnK8@l;Pe62G)LueL~EMJU*Vr( zf2)*PBIQov#V@_g{vcuenp+L9wlPYjlvd!NAU@cV0#?f|o^Nl)em>9VXJTA!LQz3xj$ zYTdIh##s?2y~e!TIjXoSjr-$!#I~ciJpbAcoxZfb{^ds

w4v&`Gg3zjSi`TcvHU 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⋘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 y3hZfJ`f+TeIEd1B!EL-rF?VX?xg-A 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 None: _assert_list(cast(List[float], a.tolist()), b) elif isinstance(a, list) and isinstance(b, np.ndarray): _assert_list(a, cast(List[float], b.tolist())) + elif isinstance(a, float) and math.isnan(a): + assert math.isnan(b) else: _assert_others(a, b) diff --git a/tests/storage/integration/data/set_id_annual.py b/tests/storage/integration/data/set_id_annual.py new file mode 100644 index 0000000000..dde1a172e0 --- /dev/null +++ b/tests/storage/integration/data/set_id_annual.py @@ -0,0 +1,327 @@ +import math + +set_id_annual = { + "columns": [ + ("OP. COST", "Euro", "min"), + ("OP. COST", "Euro", "max"), + ("MRG. PRICE", "Euro", "min"), + ("MRG. PRICE", "Euro", "max"), + ("CO2 EMIS.", "Tons", "min"), + ("CO2 EMIS.", "Tons", "max"), + ("NH3 EMIS.", "Tons", "min"), + ("NH3 EMIS.", "Tons", "max"), + ("SO2 EMIS.", "Tons", "min"), + ("SO2 EMIS.", "Tons", "max"), + ("NOX EMIS.", "Tons", "min"), + ("NOX EMIS.", "Tons", "max"), + ("PM2_5 EMIS.", "Tons", "min"), + ("PM2_5 EMIS.", "Tons", "max"), + ("PM5 EMIS.", "Tons", "min"), + ("PM5 EMIS.", "Tons", "max"), + ("PM10 EMIS.", "Tons", "min"), + ("PM10 EMIS.", "Tons", "max"), + ("NMVOC EMIS.", "Tons", "min"), + ("NMVOC EMIS.", "Tons", "max"), + ("OP1 EMIS.", "Tons", "min"), + ("OP1 EMIS.", "Tons", "max"), + ("OP2 EMIS.", "Tons", "min"), + ("OP2 EMIS.", "Tons", "max"), + ("OP3 EMIS.", "Tons", "min"), + ("OP3 EMIS.", "Tons", "max"), + ("OP4 EMIS.", "Tons", "min"), + ("OP4 EMIS.", "Tons", "max"), + ("OP5 EMIS.", "Tons", "min"), + ("OP5 EMIS.", "Tons", "max"), + ("BALANCE", "MWh", "min"), + ("BALANCE", "MWh", "max"), + ("LOAD", "MWh", "min"), + ("LOAD", "MWh", "max"), + ("H. ROR", "MWh", "min"), + ("H. ROR", "MWh", "max"), + ("NUCLEAR", "MWh", "min"), + ("NUCLEAR", "MWh", "max"), + ("LIGNITE", "MWh", "min"), + ("LIGNITE", "MWh", "max"), + ("COAL", "MWh", "min"), + ("COAL", "MWh", "max"), + ("GAS", "MWh", "min"), + ("GAS", "MWh", "max"), + ("OIL", "MWh", "min"), + ("OIL", "MWh", "max"), + ("MIX. FUEL", "MWh", "min"), + ("MIX. FUEL", "MWh", "max"), + ("MISC. DTG", "MWh", "min"), + ("MISC. DTG", "MWh", "max"), + ("MISC. DTG 2", "MWh", "min"), + ("MISC. DTG 2", "MWh", "max"), + ("MISC. DTG 3", "MWh", "min"), + ("MISC. DTG 3", "MWh", "max"), + ("MISC. DTG 4", "MWh", "min"), + ("MISC. DTG 4", "MWh", "max"), + ("WIND OFFSHORE", "MWh", "min"), + ("WIND OFFSHORE", "MWh", "max"), + ("WIND ONSHORE", "MWh", "min"), + ("WIND ONSHORE", "MWh", "max"), + ("SOLAR CONCRT.", "MWh", "min"), + ("SOLAR CONCRT.", "MWh", "max"), + ("SOLAR PV", "MWh", "min"), + ("SOLAR PV", "MWh", "max"), + ("SOLAR ROOFT", "MWh", "min"), + ("SOLAR ROOFT", "MWh", "max"), + ("RENW. 1", "MWh", "min"), + ("RENW. 1", "MWh", "max"), + ("RENW. 2", "MWh", "min"), + ("RENW. 2", "MWh", "max"), + ("RENW. 3", "MWh", "min"), + ("RENW. 3", "MWh", "max"), + ("RENW. 4", "MWh", "min"), + ("RENW. 4", "MWh", "max"), + ("H. STOR", "MWh", "min"), + ("H. STOR", "MWh", "max"), + ("H. PUMP", "MWh", "min"), + ("H. PUMP", "MWh", "max"), + ("H. LEV", "%", "min"), + ("H. LEV", "%", "max"), + ("H. INFL", "MWh", "min"), + ("H. INFL", "MWh", "max"), + ("H. OVFL", "%", "min"), + ("H. OVFL", "%", "max"), + ("H. VAL", "Euro/MWh", "min"), + ("H. VAL", "Euro/MWh", "max"), + ("H. COST", "Euro", "min"), + ("H. COST", "Euro", "max"), + ("PSP_open_injection", "MW", "min"), + ("PSP_open_injection", "MW", "max"), + ("PSP_open_withdrawal", "MW", "min"), + ("PSP_open_withdrawal", "MW", "max"), + ("PSP_open_level", "MWh", "min"), + ("PSP_open_level", "MWh", "max"), + ("PSP_closed_injection", "MW", "min"), + ("PSP_closed_injection", "MW", "max"), + ("PSP_closed_withdrawal", "MW", "min"), + ("PSP_closed_withdrawal", "MW", "max"), + ("PSP_closed_level", "MWh", "min"), + ("PSP_closed_level", "MWh", "max"), + ("Pondage_injection", "MW", "min"), + ("Pondage_injection", "MW", "max"), + ("Pondage_withdrawal", "MW", "min"), + ("Pondage_withdrawal", "MW", "max"), + ("Pondage_level", "MWh", "min"), + ("Pondage_level", "MWh", "max"), + ("Battery_injection", "MW", "min"), + ("Battery_injection", "MW", "max"), + ("Battery_withdrawal", "MW", "min"), + ("Battery_withdrawal", "MW", "max"), + ("Battery_level", "MWh", "min"), + ("Battery_level", "MWh", "max"), + ("Other1_injection", "MW", "min"), + ("Other1_injection", "MW", "max"), + ("Other1_withdrawal", "MW", "min"), + ("Other1_withdrawal", "MW", "max"), + ("Other1_level", "MWh", "min"), + ("Other1_level", "MWh", "max"), + ("Other2_injection", "MW", "min"), + ("Other2_injection", "MW", "max"), + ("Other2_withdrawal", "MW", "min"), + ("Other2_withdrawal", "MW", "max"), + ("Other2_level", "MWh", "min"), + ("Other2_level", "MWh", "max"), + ("Other3_injection", "MW", "min"), + ("Other3_injection", "MW", "max"), + ("Other3_withdrawal", "MW", "min"), + ("Other3_withdrawal", "MW", "max"), + ("Other3_level", "MWh", "min"), + ("Other3_level", "MWh", "max"), + ("Other4_injection", "MW", "min"), + ("Other4_injection", "MW", "max"), + ("Other4_withdrawal", "MW", "min"), + ("Other4_withdrawal", "MW", "max"), + ("Other4_level", "MWh", "min"), + ("Other4_level", "MWh", "max"), + ("Other5_injection", "MW", "min"), + ("Other5_injection", "MW", "max"), + ("Other5_withdrawal", "MW", "min"), + ("Other5_withdrawal", "MW", "max"), + ("Other5_level", "MWh", "min"), + ("Other5_level", "MWh", "max"), + ("UNSP. ENRG", "MWh", "min"), + ("UNSP. ENRG", "MWh", "max"), + ("SPIL. ENRG", "MWh", "min"), + ("SPIL. ENRG", "MWh", "max"), + ("LOLD", "Hours", "min"), + ("LOLD", "Hours", "max"), + ("AVL DTG", "MWh", "min"), + ("AVL DTG", "MWh", "max"), + ("DTG MRG", "MWh", "min"), + ("DTG MRG", "MWh", "max"), + ("MAX MRG", "MWh", "min"), + ("MAX MRG", "MWh", "max"), + ("NP COST", "Euro", "min"), + ("NP COST", "Euro", "max"), + ("NODU", " ", "min"), + ("NODU", " ", "max"), + ], + "data": [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + math.nan, + math.nan, + 1.0, + 1.0, + math.nan, + math.nan, + math.nan, + math.nan, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + ] + ], + "index": ["Annual"], +} diff --git a/tests/storage/integration/data/set_values_monthly.py b/tests/storage/integration/data/set_values_monthly.py new file mode 100644 index 0000000000..0cc1ad2d32 --- /dev/null +++ b/tests/storage/integration/data/set_values_monthly.py @@ -0,0 +1,4206 @@ +import math + +set_values_monthly = { + "columns": [ + ("OV. COST", "Euro", "EXP"), + ("OP. COST", "Euro", "EXP"), + ("OP. COST", "Euro", "std"), + ("OP. COST", "Euro", "min"), + ("OP. COST", "Euro", "max"), + ("MRG. PRICE", "Euro", "EXP"), + ("MRG. PRICE", "Euro", "std"), + ("MRG. PRICE", "Euro", "min"), + ("MRG. PRICE", "Euro", "max"), + ("CO2 EMIS.", "Tons", "EXP"), + ("CO2 EMIS.", "Tons", "std"), + ("CO2 EMIS.", "Tons", "min"), + ("CO2 EMIS.", "Tons", "max"), + ("NH3 EMIS.", "Tons", "EXP"), + ("NH3 EMIS.", "Tons", "std"), + ("NH3 EMIS.", "Tons", "min"), + ("NH3 EMIS.", "Tons", "max"), + ("SO2 EMIS.", "Tons", "EXP"), + ("SO2 EMIS.", "Tons", "std"), + ("SO2 EMIS.", "Tons", "min"), + ("SO2 EMIS.", "Tons", "max"), + ("NOX EMIS.", "Tons", "EXP"), + ("NOX EMIS.", "Tons", "std"), + ("NOX EMIS.", "Tons", "min"), + ("NOX EMIS.", "Tons", "max"), + ("PM2_5 EMIS.", "Tons", "EXP"), + ("PM2_5 EMIS.", "Tons", "std"), + ("PM2_5 EMIS.", "Tons", "min"), + ("PM2_5 EMIS.", "Tons", "max"), + ("PM5 EMIS.", "Tons", "EXP"), + ("PM5 EMIS.", "Tons", "std"), + ("PM5 EMIS.", "Tons", "min"), + ("PM5 EMIS.", "Tons", "max"), + ("PM10 EMIS.", "Tons", "EXP"), + ("PM10 EMIS.", "Tons", "std"), + ("PM10 EMIS.", "Tons", "min"), + ("PM10 EMIS.", "Tons", "max"), + ("NMVOC EMIS.", "Tons", "EXP"), + ("NMVOC EMIS.", "Tons", "std"), + ("NMVOC EMIS.", "Tons", "min"), + ("NMVOC EMIS.", "Tons", "max"), + ("OP1 EMIS.", "Tons", "EXP"), + ("OP1 EMIS.", "Tons", "std"), + ("OP1 EMIS.", "Tons", "min"), + ("OP1 EMIS.", "Tons", "max"), + ("OP2 EMIS.", "Tons", "EXP"), + ("OP2 EMIS.", "Tons", "std"), + ("OP2 EMIS.", "Tons", "min"), + ("OP2 EMIS.", "Tons", "max"), + ("OP3 EMIS.", "Tons", "EXP"), + ("OP3 EMIS.", "Tons", "std"), + ("OP3 EMIS.", "Tons", "min"), + ("OP3 EMIS.", "Tons", "max"), + ("OP4 EMIS.", "Tons", "EXP"), + ("OP4 EMIS.", "Tons", "std"), + ("OP4 EMIS.", "Tons", "min"), + ("OP4 EMIS.", "Tons", "max"), + ("OP5 EMIS.", "Tons", "EXP"), + ("OP5 EMIS.", "Tons", "std"), + ("OP5 EMIS.", "Tons", "min"), + ("OP5 EMIS.", "Tons", "max"), + ("BALANCE", "MWh", "EXP"), + ("BALANCE", "MWh", "std"), + ("BALANCE", "MWh", "min"), + ("BALANCE", "MWh", "max"), + ("ROW BAL.", "MWh", "values"), + ("PSP", "MWh", "EXP"), + ("MISC. NDG", "MWh", "EXP"), + ("LOAD", "MWh", "EXP"), + ("LOAD", "MWh", "std"), + ("LOAD", "MWh", "min"), + ("LOAD", "MWh", "max"), + ("H. ROR", "MWh", "EXP"), + ("H. ROR", "MWh", "std"), + ("H. ROR", "MWh", "min"), + ("H. ROR", "MWh", "max"), + ("NUCLEAR", "MWh", "EXP"), + ("NUCLEAR", "MWh", "std"), + ("NUCLEAR", "MWh", "min"), + ("NUCLEAR", "MWh", "max"), + ("LIGNITE", "MWh", "EXP"), + ("LIGNITE", "MWh", "std"), + ("LIGNITE", "MWh", "min"), + ("LIGNITE", "MWh", "max"), + ("COAL", "MWh", "EXP"), + ("COAL", "MWh", "std"), + ("COAL", "MWh", "min"), + ("COAL", "MWh", "max"), + ("GAS", "MWh", "EXP"), + ("GAS", "MWh", "std"), + ("GAS", "MWh", "min"), + ("GAS", "MWh", "max"), + ("OIL", "MWh", "EXP"), + ("OIL", "MWh", "std"), + ("OIL", "MWh", "min"), + ("OIL", "MWh", "max"), + ("MIX. FUEL", "MWh", "EXP"), + ("MIX. FUEL", "MWh", "std"), + ("MIX. FUEL", "MWh", "min"), + ("MIX. FUEL", "MWh", "max"), + ("MISC. DTG", "MWh", "EXP"), + ("MISC. DTG", "MWh", "std"), + ("MISC. DTG", "MWh", "min"), + ("MISC. DTG", "MWh", "max"), + ("MISC. DTG 2", "MWh", "EXP"), + ("MISC. DTG 2", "MWh", "std"), + ("MISC. DTG 2", "MWh", "min"), + ("MISC. DTG 2", "MWh", "max"), + ("MISC. DTG 3", "MWh", "EXP"), + ("MISC. DTG 3", "MWh", "std"), + ("MISC. DTG 3", "MWh", "min"), + ("MISC. DTG 3", "MWh", "max"), + ("MISC. DTG 4", "MWh", "EXP"), + ("MISC. DTG 4", "MWh", "std"), + ("MISC. DTG 4", "MWh", "min"), + ("MISC. DTG 4", "MWh", "max"), + ("WIND OFFSHORE", "MWh", "EXP"), + ("WIND OFFSHORE", "MWh", "std"), + ("WIND OFFSHORE", "MWh", "min"), + ("WIND OFFSHORE", "MWh", "max"), + ("WIND ONSHORE", "MWh", "EXP"), + ("WIND ONSHORE", "MWh", "std"), + ("WIND ONSHORE", "MWh", "min"), + ("WIND ONSHORE", "MWh", "max"), + ("SOLAR CONCRT.", "MWh", "EXP"), + ("SOLAR CONCRT.", "MWh", "std"), + ("SOLAR CONCRT.", "MWh", "min"), + ("SOLAR CONCRT.", "MWh", "max"), + ("SOLAR PV", "MWh", "EXP"), + ("SOLAR PV", "MWh", "std"), + ("SOLAR PV", "MWh", "min"), + ("SOLAR PV", "MWh", "max"), + ("SOLAR ROOFT", "MWh", "EXP"), + ("SOLAR ROOFT", "MWh", "std"), + ("SOLAR ROOFT", "MWh", "min"), + ("SOLAR ROOFT", "MWh", "max"), + ("RENW. 1", "MWh", "EXP"), + ("RENW. 1", "MWh", "std"), + ("RENW. 1", "MWh", "min"), + ("RENW. 1", "MWh", "max"), + ("RENW. 2", "MWh", "EXP"), + ("RENW. 2", "MWh", "std"), + ("RENW. 2", "MWh", "min"), + ("RENW. 2", "MWh", "max"), + ("RENW. 3", "MWh", "EXP"), + ("RENW. 3", "MWh", "std"), + ("RENW. 3", "MWh", "min"), + ("RENW. 3", "MWh", "max"), + ("RENW. 4", "MWh", "EXP"), + ("RENW. 4", "MWh", "std"), + ("RENW. 4", "MWh", "min"), + ("RENW. 4", "MWh", "max"), + ("H. STOR", "MWh", "EXP"), + ("H. STOR", "MWh", "std"), + ("H. STOR", "MWh", "min"), + ("H. STOR", "MWh", "max"), + ("H. PUMP", "MWh", "EXP"), + ("H. PUMP", "MWh", "std"), + ("H. PUMP", "MWh", "min"), + ("H. PUMP", "MWh", "max"), + ("H. LEV", "%", "EXP"), + ("H. LEV", "%", "std"), + ("H. LEV", "%", "min"), + ("H. LEV", "%", "max"), + ("H. INFL", "MWh", "EXP"), + ("H. INFL", "MWh", "std"), + ("H. INFL", "MWh", "min"), + ("H. INFL", "MWh", "max"), + ("H. OVFL", "%", "EXP"), + ("H. OVFL", "%", "std"), + ("H. OVFL", "%", "min"), + ("H. OVFL", "%", "max"), + ("H. VAL", "Euro/MWh", "EXP"), + ("H. VAL", "Euro/MWh", "std"), + ("H. VAL", "Euro/MWh", "min"), + ("H. VAL", "Euro/MWh", "max"), + ("H. COST", "Euro", "EXP"), + ("H. COST", "Euro", "std"), + ("H. COST", "Euro", "min"), + ("H. COST", "Euro", "max"), + ("PSP_open_injection", "MW", "EXP"), + ("PSP_open_injection", "MW", "std"), + ("PSP_open_injection", "MW", "min"), + ("PSP_open_injection", "MW", "max"), + ("PSP_open_withdrawal", "MW", "EXP"), + ("PSP_open_withdrawal", "MW", "std"), + ("PSP_open_withdrawal", "MW", "min"), + ("PSP_open_withdrawal", "MW", "max"), + ("PSP_open_level", "MWh", "EXP"), + ("PSP_open_level", "MWh", "std"), + ("PSP_open_level", "MWh", "min"), + ("PSP_open_level", "MWh", "max"), + ("PSP_closed_injection", "MW", "EXP"), + ("PSP_closed_injection", "MW", "std"), + ("PSP_closed_injection", "MW", "min"), + ("PSP_closed_injection", "MW", "max"), + ("PSP_closed_withdrawal", "MW", "EXP"), + ("PSP_closed_withdrawal", "MW", "std"), + ("PSP_closed_withdrawal", "MW", "min"), + ("PSP_closed_withdrawal", "MW", "max"), + ("PSP_closed_level", "MWh", "EXP"), + ("PSP_closed_level", "MWh", "std"), + ("PSP_closed_level", "MWh", "min"), + ("PSP_closed_level", "MWh", "max"), + ("Pondage_injection", "MW", "EXP"), + ("Pondage_injection", "MW", "std"), + ("Pondage_injection", "MW", "min"), + ("Pondage_injection", "MW", "max"), + ("Pondage_withdrawal", "MW", "EXP"), + ("Pondage_withdrawal", "MW", "std"), + ("Pondage_withdrawal", "MW", "min"), + ("Pondage_withdrawal", "MW", "max"), + ("Pondage_level", "MWh", "EXP"), + ("Pondage_level", "MWh", "std"), + ("Pondage_level", "MWh", "min"), + ("Pondage_level", "MWh", "max"), + ("Battery_injection", "MW", "EXP"), + ("Battery_injection", "MW", "std"), + ("Battery_injection", "MW", "min"), + ("Battery_injection", "MW", "max"), + ("Battery_withdrawal", "MW", "EXP"), + ("Battery_withdrawal", "MW", "std"), + ("Battery_withdrawal", "MW", "min"), + ("Battery_withdrawal", "MW", "max"), + ("Battery_level", "MWh", "EXP"), + ("Battery_level", "MWh", "std"), + ("Battery_level", "MWh", "min"), + ("Battery_level", "MWh", "max"), + ("Other1_injection", "MW", "EXP"), + ("Other1_injection", "MW", "std"), + ("Other1_injection", "MW", "min"), + ("Other1_injection", "MW", "max"), + ("Other1_withdrawal", "MW", "EXP"), + ("Other1_withdrawal", "MW", "std"), + ("Other1_withdrawal", "MW", "min"), + ("Other1_withdrawal", "MW", "max"), + ("Other1_level", "MWh", "EXP"), + ("Other1_level", "MWh", "std"), + ("Other1_level", "MWh", "min"), + ("Other1_level", "MWh", "max"), + ("Other2_injection", "MW", "EXP"), + ("Other2_injection", "MW", "std"), + ("Other2_injection", "MW", "min"), + ("Other2_injection", "MW", "max"), + ("Other2_withdrawal", "MW", "EXP"), + ("Other2_withdrawal", "MW", "std"), + ("Other2_withdrawal", "MW", "min"), + ("Other2_withdrawal", "MW", "max"), + ("Other2_level", "MWh", "EXP"), + ("Other2_level", "MWh", "std"), + ("Other2_level", "MWh", "min"), + ("Other2_level", "MWh", "max"), + ("Other3_injection", "MW", "EXP"), + ("Other3_injection", "MW", "std"), + ("Other3_injection", "MW", "min"), + ("Other3_injection", "MW", "max"), + ("Other3_withdrawal", "MW", "EXP"), + ("Other3_withdrawal", "MW", "std"), + ("Other3_withdrawal", "MW", "min"), + ("Other3_withdrawal", "MW", "max"), + ("Other3_level", "MWh", "EXP"), + ("Other3_level", "MWh", "std"), + ("Other3_level", "MWh", "min"), + ("Other3_level", "MWh", "max"), + ("Other4_injection", "MW", "EXP"), + ("Other4_injection", "MW", "std"), + ("Other4_injection", "MW", "min"), + ("Other4_injection", "MW", "max"), + ("Other4_withdrawal", "MW", "EXP"), + ("Other4_withdrawal", "MW", "std"), + ("Other4_withdrawal", "MW", "min"), + ("Other4_withdrawal", "MW", "max"), + ("Other4_level", "MWh", "EXP"), + ("Other4_level", "MWh", "std"), + ("Other4_level", "MWh", "min"), + ("Other4_level", "MWh", "max"), + ("Other5_injection", "MW", "EXP"), + ("Other5_injection", "MW", "std"), + ("Other5_injection", "MW", "min"), + ("Other5_injection", "MW", "max"), + ("Other5_withdrawal", "MW", "EXP"), + ("Other5_withdrawal", "MW", "std"), + ("Other5_withdrawal", "MW", "min"), + ("Other5_withdrawal", "MW", "max"), + ("Other5_level", "MWh", "EXP"), + ("Other5_level", "MWh", "std"), + ("Other5_level", "MWh", "min"), + ("Other5_level", "MWh", "max"), + ("UNSP. ENRG", "MWh", "EXP"), + ("UNSP. ENRG", "MWh", "std"), + ("UNSP. ENRG", "MWh", "min"), + ("UNSP. ENRG", "MWh", "max"), + ("SPIL. ENRG", "MWh", "EXP"), + ("SPIL. ENRG", "MWh", "std"), + ("SPIL. ENRG", "MWh", "min"), + ("SPIL. ENRG", "MWh", "max"), + ("LOLD", "Hours", "EXP"), + ("LOLD", "Hours", "std"), + ("LOLD", "Hours", "min"), + ("LOLD", "Hours", "max"), + ("LOLP", "%", "values"), + ("AVL DTG", "MWh", "EXP"), + ("AVL DTG", "MWh", "std"), + ("AVL DTG", "MWh", "min"), + ("AVL DTG", "MWh", "max"), + ("DTG MRG", "MWh", "EXP"), + ("DTG MRG", "MWh", "std"), + ("DTG MRG", "MWh", "min"), + ("DTG MRG", "MWh", "max"), + ("MAX MRG", "MWh", "EXP"), + ("MAX MRG", "MWh", "std"), + ("MAX MRG", "MWh", "min"), + ("MAX MRG", "MWh", "max"), + ("NP COST", "Euro", "EXP"), + ("NP COST", "Euro", "std"), + ("NP COST", "Euro", "min"), + ("NP COST", "Euro", "max"), + ("NODU", " ", "EXP"), + ("NODU", " ", "std"), + ("NODU", " ", "min"), + ("NODU", " ", "max"), + ], + "data": [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.0, + 0.0, + -0.0, + -0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + math.nan, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ], + "index": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"], +} diff --git a/tests/storage/integration/test_STA_mini.py b/tests/storage/integration/test_STA_mini.py index e83cda5847..c7ce7c03f1 100644 --- a/tests/storage/integration/test_STA_mini.py +++ b/tests/storage/integration/test_STA_mini.py @@ -20,6 +20,8 @@ from tests.helpers import assert_study from tests.storage.integration.data.de_details_hourly import de_details_hourly from tests.storage.integration.data.de_fr_values_hourly import de_fr_values_hourly +from tests.storage.integration.data.set_id_annual import set_id_annual +from tests.storage.integration.data.set_values_monthly import set_values_monthly ADMIN = JWTUser( id=1, @@ -308,6 +310,31 @@ def test_sta_mini_input(storage_service, url: str, expected_output: dict): @pytest.mark.parametrize( "url, expected_output", [ + ( + "/v1/studies/STA-mini/raw?path=output/20241807-1540eco-extra-outputs/economy/mc-all/binding_constraints/binding-constraints-annual", + { + "columns": [ + ("contrainte (<)", " ", "EXP"), + ("contrainte (<)", " ", "std"), + ("contrainte (<)", " ", "min"), + ("contrainte (<)", " ", "max"), + ], + "index": ["Annual"], + "data": [[0.0, 0.0, 0.0, 0.0]], + }, + ), + ( + "/v1/studies/STA-mini/raw?path=output/20241807-1540eco-extra-outputs/economy/mc-all/areas/@ all areas/values-monthly", + set_values_monthly, + ), + ( + "/v1/studies/STA-mini/raw?path=output/20241807-1540eco-extra-outputs/economy/mc-all/areas/@ all areas/id-annual", + set_id_annual, + ), + ( + "/v1/studies/STA-mini/raw?path=output/20241807-1540eco-extra-outputs/ts-numbers/bindingconstraints/default", + [1], + ), ( "/v1/studies/STA-mini/raw?path=output/20201014-1422eco-hello/annualSystemCost", b"EXP : 185808000\nSTD : 0\nMIN : 185808000\nMAX : 185808000\n", @@ -354,28 +381,11 @@ def test_sta_mini_input(storage_service, url: str, expected_output: dict): ), ( "/v1/studies/STA-mini/raw?path=output/20201014-1422eco-hello/economy/mc-all/links/de/fr", - { - "values-hourly": "matrixfile://values-hourly.txt", - "id-hourly": "matrixfile://id-hourly.txt", - "values-daily": "matrixfile://values-daily.txt", - "id-daily": "matrixfile://id-daily.txt", - "values-weekly": "matrixfile://values-weekly.txt", - "id-weekly": "matrixfile://id-weekly.txt", - "values-monthly": "matrixfile://values-monthly.txt", - "id-monthly": "matrixfile://id-monthly.txt", - "values-annual": "matrixfile://values-annual.txt", - "id-annual": "matrixfile://id-annual.txt", - }, + {}, ), ( "/v1/studies/STA-mini/raw?path=output/20201014-1422eco-hello/economy/mc-ind/00001/links/de/fr", - { - "values-hourly": "matrixfile://values-hourly.txt", - "values-daily": "matrixfile://values-daily.txt", - "values-weekly": "matrixfile://values-weekly.txt", - "values-monthly": "matrixfile://values-monthly.txt", - "values-annual": "matrixfile://values-annual.txt", - }, + {"values-hourly": "matrixfile://values-hourly.txt"}, ), ( "/v1/studies/STA-mini/raw?path=output/20201014-1422eco-hello/economy/mc-ind/00001/links/de/fr/values-hourly", diff --git a/tests/storage/integration/test_exporter.py b/tests/storage/integration/test_exporter.py index 3e4e5666f3..5c273837e4 100644 --- a/tests/storage/integration/test_exporter.py +++ b/tests/storage/integration/test_exporter.py @@ -131,7 +131,7 @@ def test_export_flat( assert export_output_path.exists() files = set(export_output_path.iterdir()) if output_list is None: - assert len(files) == 5 + assert len(files) == 6 elif len(output_list) == 0: assert not files else: diff --git a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_area.py b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_area.py index 34be106791..2ff4f6a44a 100644 --- a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_area.py +++ b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_area.py @@ -1,3 +1,4 @@ +import typing as t import uuid from pathlib import Path from unittest.mock import Mock @@ -12,81 +13,36 @@ from antarest.study.storage.rawstudy.model.filesystem.matrix.output_series_matrix import AreaOutputSeriesMatrix from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common import area -# noinspection SpellCheckingInspection -MC_ALL_TRUE = { - "details-annual": {"freq": MatrixFrequency.ANNUAL}, - "details-daily": {"freq": MatrixFrequency.DAILY}, - "details-hourly": {"freq": MatrixFrequency.HOURLY}, - "details-monthly": {"freq": MatrixFrequency.MONTHLY}, - "details-res-annual": {"freq": MatrixFrequency.ANNUAL}, - "details-res-daily": {"freq": MatrixFrequency.DAILY}, - "details-res-hourly": {"freq": MatrixFrequency.HOURLY}, - "details-res-monthly": {"freq": MatrixFrequency.MONTHLY}, - "details-res-weekly": {"freq": MatrixFrequency.WEEKLY}, - "details-weekly": {"freq": MatrixFrequency.WEEKLY}, - "id-annual": {"freq": MatrixFrequency.ANNUAL}, - "id-daily": {"freq": MatrixFrequency.DAILY}, - "id-hourly": {"freq": MatrixFrequency.HOURLY}, - "id-monthly": {"freq": MatrixFrequency.MONTHLY}, - "id-weekly": {"freq": MatrixFrequency.WEEKLY}, - "values-annual": {"freq": MatrixFrequency.ANNUAL}, - "values-daily": {"freq": MatrixFrequency.DAILY}, - "values-hourly": {"freq": MatrixFrequency.HOURLY}, - "values-monthly": {"freq": MatrixFrequency.MONTHLY}, - "values-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - -# noinspection SpellCheckingInspection -MC_ALL_FALSE = { - "details-annual": {"freq": MatrixFrequency.ANNUAL}, - "details-daily": {"freq": MatrixFrequency.DAILY}, - "details-hourly": {"freq": MatrixFrequency.HOURLY}, - "details-monthly": {"freq": MatrixFrequency.MONTHLY}, - "details-res-annual": {"freq": MatrixFrequency.ANNUAL}, - "details-res-daily": {"freq": MatrixFrequency.DAILY}, - "details-res-hourly": {"freq": MatrixFrequency.HOURLY}, - "details-res-monthly": {"freq": MatrixFrequency.MONTHLY}, - "details-res-weekly": {"freq": MatrixFrequency.WEEKLY}, - "details-weekly": {"freq": MatrixFrequency.WEEKLY}, - "values-annual": {"freq": MatrixFrequency.ANNUAL}, - "values-daily": {"freq": MatrixFrequency.DAILY}, - "values-hourly": {"freq": MatrixFrequency.HOURLY}, - "values-monthly": {"freq": MatrixFrequency.MONTHLY}, - "values-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - class TestOutputSimulationAreaItem: @pytest.mark.parametrize( - "mc_all, expected", + "existing_files", [ - pytest.param(True, MC_ALL_TRUE, id="mc-all-True"), - pytest.param(False, MC_ALL_FALSE, id="mc-all-False"), + pytest.param(["details-annual.txt"]), + pytest.param(["details-res-hourly.txt", "values-monthly.txt", "details-STstorage-daily.txt"]), + pytest.param([]), ], ) - def test_build_output_simulation_area_item( - self, - mc_all: bool, - expected: dict, - ): + def test_build_output_simulation_area_item(self, existing_files: t.List[str], tmp_path: Path): + expected = {} + for file in existing_files: + tmp_path.joinpath(file).touch() + name = Path(file).stem + splitted = name.split("-") + expected[name] = {"freq": MatrixFrequency(splitted[len(splitted) - 1])} matrix = Mock(spec=ISimpleMatrixService) resolver = Mock(spec=UriResolverService) context = ContextServer(matrix=matrix, resolver=resolver) study_id = str(uuid.uuid4()) config = FileStudyTreeConfig( study_path=Path("path/to/study"), - path=Path("path/to/study"), + path=tmp_path, study_id=study_id, version=850, # will become a `str` in the future areas={}, ) - node = area.OutputSimulationAreaItem( - context=context, - config=config, - area="fr", - mc_all=mc_all, - ) + node = area.OutputSimulationAreaItem(context=context, config=config, area="fr") actual = node.build() # check the result @@ -96,25 +52,15 @@ def test_build_output_simulation_area_item( new_config = FileStudyTreeConfig( study_path=Path("path/to/study"), - path=Path("path/to/study"), + path=tmp_path, study_id=study_id, version=860, # will become a `str` in the future areas={}, ) - new_node = area.OutputSimulationAreaItem( - context=context, - config=new_config, - area="fr", - mc_all=mc_all, - ) + new_node = area.OutputSimulationAreaItem(context=context, config=new_config, area="fr") new_actual = new_node.build() # check the result actual_obj = {key: {"freq": value.freq} for key, value in new_actual.items()} - expected["details-STstorage-annual"] = {"freq": MatrixFrequency.ANNUAL} - expected["details-STstorage-daily"] = {"freq": MatrixFrequency.DAILY} - expected["details-STstorage-hourly"] = {"freq": MatrixFrequency.HOURLY} - expected["details-STstorage-monthly"] = {"freq": MatrixFrequency.MONTHLY} - expected["details-STstorage-weekly"] = {"freq": MatrixFrequency.WEEKLY} assert actual_obj == expected diff --git a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_binding_const.py b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_binding_const.py index 0b3161d193..248468d5de 100644 --- a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_binding_const.py +++ b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_binding_const.py @@ -1,3 +1,4 @@ +import typing as t import uuid from pathlib import Path from unittest.mock import Mock @@ -14,44 +15,34 @@ ) from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common import binding_const -# noinspection SpellCheckingInspection -NOMINAL_CASE = { - "binding-constraints-annual": {"freq": MatrixFrequency.ANNUAL}, - "binding-constraints-daily": {"freq": MatrixFrequency.DAILY}, - "binding-constraints-hourly": {"freq": MatrixFrequency.HOURLY}, - "binding-constraints-monthly": {"freq": MatrixFrequency.MONTHLY}, - "binding-constraints-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - class TestOutputSimulationBindingConstraintItem: @pytest.mark.parametrize( - "expected", + "existing_files", [ - pytest.param(NOMINAL_CASE, id="nominal-case-True"), + pytest.param(["binding-constraints-hourly.txt", "binding-constraints-daily.txt"]), + pytest.param([]), ], ) - def test_build_output_simulation_binding_constraint_item( - self, - expected: dict, - ): + def test_build_output_simulation_binding_constraint_item(self, existing_files: t.List[str], tmp_path: Path): + expected = {} + for file in existing_files: + tmp_path.joinpath(file).touch() + name = Path(file).stem + expected[name] = {"freq": MatrixFrequency(name.replace("binding-constraints-", ""))} matrix = Mock(spec=ISimpleMatrixService) resolver = Mock(spec=UriResolverService) context = ContextServer(matrix=matrix, resolver=resolver) study_id = str(uuid.uuid4()) config = FileStudyTreeConfig( study_path=Path("path/to/study"), - path=Path("path/to/study"), + path=tmp_path, study_id=study_id, version=850, # will become a `str` in the future areas={}, ) - node = binding_const.OutputSimulationBindingConstraintItem( - context=context, - config=config, - children_glob_exceptions=None, - ) + node = binding_const.OutputSimulationBindingConstraintItem(context=context, config=config) actual = node.build() # check the result diff --git a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_link.py b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_link.py index 3c7dcdb1d2..765187a186 100644 --- a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_link.py +++ b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_link.py @@ -1,3 +1,4 @@ +import typing as t import uuid from pathlib import Path from unittest.mock import Mock @@ -12,62 +13,34 @@ from antarest.study.storage.rawstudy.model.filesystem.matrix.output_series_matrix import LinkOutputSeriesMatrix from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common import link -# noinspection SpellCheckingInspection -MC_ALL_TRUE = { - "id-annual": {"freq": MatrixFrequency.ANNUAL}, - "id-daily": {"freq": MatrixFrequency.DAILY}, - "id-hourly": {"freq": MatrixFrequency.HOURLY}, - "id-monthly": {"freq": MatrixFrequency.MONTHLY}, - "id-weekly": {"freq": MatrixFrequency.WEEKLY}, - "values-annual": {"freq": MatrixFrequency.ANNUAL}, - "values-daily": {"freq": MatrixFrequency.DAILY}, - "values-hourly": {"freq": MatrixFrequency.HOURLY}, - "values-monthly": {"freq": MatrixFrequency.MONTHLY}, - "values-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - -# noinspection SpellCheckingInspection -MC_ALL_FALSE = { - "values-annual": {"freq": MatrixFrequency.ANNUAL}, - "values-daily": {"freq": MatrixFrequency.DAILY}, - "values-hourly": {"freq": MatrixFrequency.HOURLY}, - "values-monthly": {"freq": MatrixFrequency.MONTHLY}, - "values-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - class TestOutputSimulationLinkItem: @pytest.mark.parametrize( - "mc_all, expected", + "existing_files", [ - pytest.param(True, MC_ALL_TRUE, id="mc-all-True"), - pytest.param(False, MC_ALL_FALSE, id="mc-all-False"), + pytest.param(["id-hourly.txt"]), + pytest.param(["values-monthly.txt", "id-annual.txt"]), ], ) - def test_build_output_simulation_link_item( - self, - mc_all: bool, - expected: dict, - ): + def test_build_output_simulation_link_item(self, existing_files: t.List[str], tmp_path: Path): + expected = {} + for file in existing_files: + tmp_path.joinpath(file).touch() + name = Path(file).stem + expected[name] = {"freq": MatrixFrequency(name.split("-")[1])} matrix = Mock(spec=ISimpleMatrixService) resolver = Mock(spec=UriResolverService) context = ContextServer(matrix=matrix, resolver=resolver) study_id = str(uuid.uuid4()) config = FileStudyTreeConfig( study_path=Path("path/to/study"), - path=Path("path/to/study"), + path=tmp_path, study_id=study_id, version=850, # will become a `str` in the future areas={}, ) - node = link.OutputSimulationLinkItem( - context=context, - config=config, - area="fr", - link="fr -> de", - mc_all=mc_all, - ) + node = link.OutputSimulationLinkItem(context=context, config=config, area="fr", link="fr -> de") actual = node.build() # check the result diff --git a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_set.py b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_set.py index c56f1dc8ff..0213647a8e 100644 --- a/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_set.py +++ b/tests/storage/repository/filesystem/root/output/simulation/mode/common/test_set.py @@ -1,3 +1,4 @@ +import typing as t import uuid from pathlib import Path from unittest.mock import Mock @@ -12,61 +13,34 @@ from antarest.study.storage.rawstudy.model.filesystem.matrix.output_series_matrix import AreaOutputSeriesMatrix from antarest.study.storage.rawstudy.model.filesystem.root.output.simulation.mode.common import set -# noinspection SpellCheckingInspection -MC_ALL_TRUE = { - "id-annual": {"freq": MatrixFrequency.ANNUAL}, - "id-daily": {"freq": MatrixFrequency.DAILY}, - "id-hourly": {"freq": MatrixFrequency.HOURLY}, - "id-monthly": {"freq": MatrixFrequency.MONTHLY}, - "id-weekly": {"freq": MatrixFrequency.WEEKLY}, - "values-annual": {"freq": MatrixFrequency.ANNUAL}, - "values-daily": {"freq": MatrixFrequency.DAILY}, - "values-hourly": {"freq": MatrixFrequency.HOURLY}, - "values-monthly": {"freq": MatrixFrequency.MONTHLY}, - "values-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - -# noinspection SpellCheckingInspection -MC_ALL_FALSE = { - "values-annual": {"freq": MatrixFrequency.ANNUAL}, - "values-daily": {"freq": MatrixFrequency.DAILY}, - "values-hourly": {"freq": MatrixFrequency.HOURLY}, - "values-monthly": {"freq": MatrixFrequency.MONTHLY}, - "values-weekly": {"freq": MatrixFrequency.WEEKLY}, -} - class TestOutputSimulationSet: @pytest.mark.parametrize( - "mc_all, expected", + "existing_files", [ - pytest.param(True, MC_ALL_TRUE, id="mc-all-True"), - pytest.param(False, MC_ALL_FALSE, id="mc-all-False"), + pytest.param(["id-hourly.txt", "values-annual.txt"]), + pytest.param([]), ], ) - def test_output_simulation_set( - self, - mc_all: bool, - expected: dict, - ): + def test_output_simulation_set(self, existing_files: t.List[str], tmp_path: Path): + expected = {} + for file in existing_files: + tmp_path.joinpath(file).touch() + name = Path(file).stem + expected[name] = {"freq": MatrixFrequency(name.split("-")[1])} matrix = Mock(spec=ISimpleMatrixService) resolver = Mock(spec=UriResolverService) context = ContextServer(matrix=matrix, resolver=resolver) study_id = str(uuid.uuid4()) config = FileStudyTreeConfig( - study_path=Path("path/to/study"), - path=Path("path/to/study"), + study_path=Path("study_path"), + path=tmp_path, study_id=study_id, version=850, # will become a `str` in the future areas={}, ) - node = set.OutputSimulationSet( - context=context, - config=config, - set="foo", - mc_all=mc_all, - ) + node = set.OutputSimulationSet(context=context, config=config, set="foo") actual = node.build() # check the result diff --git a/tests/storage/repository/filesystem/utils.py b/tests/storage/repository/filesystem/utils.py index abef9e26e5..cb563e8567 100644 --- a/tests/storage/repository/filesystem/utils.py +++ b/tests/storage/repository/filesystem/utils.py @@ -54,7 +54,7 @@ def __init__( config: FileStudyTreeConfig, children: TREE, ): - FolderNode.__init__(self, context, config) + super().__init__(context, config) self.children = children def build(self) -> TREE: From 5ad8c1d086a691ebb765d71dd3263d2707eab398 Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE <43534797+laurent-laporte-pro@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:04:39 +0200 Subject: [PATCH 07/17] feat(api-raw): raise a 404 Not Found error when a resource is missing in the study (#2078) --- .../filesystem/matrix/input_series_matrix.py | 34 ++- .../filesystem/matrix/output_series_matrix.py | 24 +- .../test_binding_constraints.py | 279 ++++-------------- .../matrix/input_series_matrix_test.py | 42 --- .../matrix/output_series_matrix_test.py | 91 ------ ...alizer_test.py => test_date_serializer.py} | 0 ...ead_writer_test.py => test_head_writer.py} | 0 .../matrix/test_input_series_matrix.py | 94 ++++++ .../matrix/test_output_series_matrix.py | 116 ++++++++ 9 files changed, 304 insertions(+), 376 deletions(-) delete mode 100644 tests/storage/repository/filesystem/matrix/input_series_matrix_test.py delete mode 100644 tests/storage/repository/filesystem/matrix/output_series_matrix_test.py rename tests/storage/repository/filesystem/matrix/{date_serializer_test.py => test_date_serializer.py} (100%) rename tests/storage/repository/filesystem/matrix/{head_writer_test.py => test_head_writer.py} (100%) create mode 100644 tests/storage/repository/filesystem/matrix/test_input_series_matrix.py create mode 100644 tests/storage/repository/filesystem/matrix/test_output_series_matrix.py diff --git a/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py b/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py index 9be78332f3..4cda0b4027 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py +++ b/antarest/study/storage/rawstudy/model/filesystem/matrix/input_series_matrix.py @@ -11,6 +11,7 @@ from antarest.core.utils.utils import StopWatch from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer +from antarest.study.storage.rawstudy.model.filesystem.folder_node import ChildNotFoundError from antarest.study.storage.rawstudy.model.filesystem.matrix.matrix import MatrixFrequency, MatrixNode logger = logging.getLogger(__name__) @@ -49,23 +50,28 @@ def parse( try: # sourcery skip: extract-method stopwatch = StopWatch() - if self.get_link_path().exists(): - link = self.get_link_path().read_text() + link_path = self.get_link_path() + if link_path.exists(): + link = link_path.read_text() matrix_json = self.context.resolver.resolve(link) matrix_json = cast(JSON, matrix_json) - matrix: pd.DataFrame = pd.DataFrame( - data=matrix_json["data"], - columns=matrix_json["columns"], - index=matrix_json["index"], - ) + matrix: pd.DataFrame = pd.DataFrame(**matrix_json) else: - matrix = pd.read_csv( - file_path, - sep="\t", - dtype=float, - header=None, - float_precision="legacy", - ) + try: + matrix = pd.read_csv( + file_path, + sep="\t", + dtype=float, + header=None, + float_precision="legacy", + ) + except FileNotFoundError as e: + # Raise 404 'Not Found' if the TSV file is not found + logger.warning(f"Matrix file'{file_path}' not found") + study_id = self.config.study_id + relpath = file_path.relative_to(self.config.study_path).as_posix() + raise ChildNotFoundError(f"File '{relpath}' not found in the study '{study_id}'") from e + stopwatch.log_elapsed(lambda x: logger.info(f"Matrix parsed in {x}s")) matrix.dropna(how="any", axis=1, inplace=True) if return_dataframe: diff --git a/antarest/study/storage/rawstudy/model/filesystem/matrix/output_series_matrix.py b/antarest/study/storage/rawstudy/model/filesystem/matrix/output_series_matrix.py index 6f82eaab34..dbc3c4385e 100644 --- a/antarest/study/storage/rawstudy/model/filesystem/matrix/output_series_matrix.py +++ b/antarest/study/storage/rawstudy/model/filesystem/matrix/output_series_matrix.py @@ -50,6 +50,7 @@ def get_lazy_content( depth: int = -1, expanded: bool = False, ) -> str: + # noinspection SpellCheckingInspection return f"matrixfile://{self.config.path.name}" def parse_dataframe( @@ -58,14 +59,21 @@ def parse_dataframe( tmp_dir: Any = None, ) -> DataFrame: file_path = file_path or self.config.path - df = pd.read_csv( - file_path, - sep="\t", - skiprows=4, - header=[0, 1, 2], - na_values="N/A", - float_precision="legacy", - ) + try: + df = pd.read_csv( + file_path, + sep="\t", + skiprows=4, + header=[0, 1, 2], + na_values="N/A", + float_precision="legacy", + ) + except FileNotFoundError as e: + # Raise 404 'Not Found' if the TSV file is not found + logger.warning(f"Matrix file'{file_path}' not found") + study_id = self.config.study_id + relpath = file_path.relative_to(self.config.study_path).as_posix() + raise ChildNotFoundError(f"File '{relpath}' not found in the study '{study_id}'") from e if tmp_dir: tmp_dir.cleanup() diff --git a/tests/integration/study_data_blueprint/test_binding_constraints.py b/tests/integration/study_data_blueprint/test_binding_constraints.py index af537fcc7f..7e3c613e16 100644 --- a/tests/integration/study_data_blueprint/test_binding_constraints.py +++ b/tests/integration/study_data_blueprint/test_binding_constraints.py @@ -46,6 +46,7 @@ def test_constraint_id__link(self) -> None: offset=123, data=LinkTerm(area1="Area 1", area2="Area 2"), ) + assert term.data is not None assert term.generate_id() == term.data.generate_id() def test_constraint_id__cluster(self) -> None: @@ -55,6 +56,7 @@ def test_constraint_id__cluster(self) -> None: offset=123, data=ClusterTerm(area="Area 1", cluster="Cluster X"), ) + assert term.data is not None assert term.generate_id() == term.data.generate_id() def test_constraint_id__other(self) -> None: @@ -66,18 +68,11 @@ def test_constraint_id__other(self) -> None: assert term.generate_id() == "foo" -def _upload_matrix( - client: TestClient, user_access_token: str, study_id: str, matrix_path: str, df: pd.DataFrame -) -> None: +def _upload_matrix(client: TestClient, study_id: str, matrix_path: str, df: pd.DataFrame) -> None: tsv = io.BytesIO() df.to_csv(tsv, sep="\t", index=False, header=False) tsv.seek(0) - res = client.put( - f"/v1/studies/{study_id}/raw", - params={"path": matrix_path}, - headers={"Authorization": f"Bearer {user_access_token}"}, - files={"file": tsv}, - ) + res = client.put(f"/v1/studies/{study_id}/raw", params={"path": matrix_path}, files={"file": tsv}) res.raise_for_status() @@ -89,72 +84,43 @@ class TestBindingConstraints: @pytest.mark.parametrize("study_type", ["raw", "variant"]) def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, study_type: str) -> None: - user_headers = {"Authorization": f"Bearer {user_access_token}"} + client.headers = {"Authorization": f"Bearer {user_access_token}"} # type: ignore # ============================= # STUDY PREPARATION # ============================= # Create a Study - res = client.post( - "/v1/studies", - headers=user_headers, - params={"name": "foo", "version": "860"}, - ) + res = client.post("/v1/studies", params={"name": "foo", "version": "860"}) assert res.status_code == 201, res.json() study_id = res.json() # Create Areas - res = client.post( - f"/v1/studies/{study_id}/areas", - headers=user_headers, - json={ - "name": "Area 1", - "type": "AREA", - }, - ) + res = client.post(f"/v1/studies/{study_id}/areas", json={"name": "Area 1", "type": "AREA"}) assert res.status_code == 200, res.json() area1_id = res.json()["id"] assert area1_id == "area 1" - res = client.post( - f"/v1/studies/{study_id}/areas", - headers=user_headers, - json={ - "name": "Area 2", - "type": "AREA", - }, - ) + res = client.post(f"/v1/studies/{study_id}/areas", json={"name": "Area 2", "type": "AREA"}) assert res.status_code == 200, res.json() area2_id = res.json()["id"] assert area2_id == "area 2" # Create a link between the two areas - res = client.post( - f"/v1/studies/{study_id}/links", - headers=user_headers, - json={ - "area1": area1_id, - "area2": area2_id, - }, - ) + res = client.post(f"/v1/studies/{study_id}/links", json={"area1": area1_id, "area2": area2_id}) assert res.status_code == 200, res.json() # Create a cluster in area1 res = client.post( f"/v1/studies/{study_id}/areas/{area1_id}/clusters/thermal", - headers=user_headers, - json={ - "name": "Cluster 1", - "group": "Nuclear", - }, + json={"name": "Cluster 1", "group": "Nuclear"}, ) assert res.status_code == 200, res.json() cluster_id = res.json()["id"] assert cluster_id == "Cluster 1" # Get clusters list to check created cluster in area1 - res = client.get(f"/v1/studies/{study_id}/areas/{area1_id}/clusters/thermal", headers=user_headers) + res = client.get(f"/v1/studies/{study_id}/areas/{area1_id}/clusters/thermal") clusters_list = res.json() assert res.status_code == 200, res.json() assert len(clusters_list) == 1 @@ -164,11 +130,7 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st if study_type == "variant": # Create Variant - res = client.post( - f"/v1/studies/{study_id}/variants", - headers=user_headers, - params={"name": "Variant 1"}, - ) + res = client.post(f"/v1/studies/{study_id}/variants", params={"name": "Variant 1"}) assert res.status_code in {200, 201}, res.json() study_id = res.json() @@ -192,7 +154,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st }, } ], - headers=user_headers, ) assert res.status_code in {200, 201}, res.json() @@ -211,7 +172,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st }, } ], - headers=user_headers, ) assert res.status_code in {200, 201}, res.json() @@ -226,12 +186,11 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "terms": [], "comments": "New API", }, - headers=user_headers, ) assert res.status_code in {200, 201}, res.json() # Get Binding Constraint list - res = client.get(f"/v1/studies/{study_id}/bindingconstraints", headers=user_headers) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints") binding_constraints_list = res.json() assert res.status_code == 200, res.json() assert len(binding_constraints_list) == 3 @@ -278,7 +237,7 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st bc_id = binding_constraints_list[0]["id"] # Asserts binding constraint configuration is valid. - res = client.get(f"/v1/studies/{study_id}/constraint-groups", headers=user_headers) + res = client.get(f"/v1/studies/{study_id}/constraint-groups") assert res.status_code == 200, res.json() # ============================= @@ -293,7 +252,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "offset": 2, "data": {"area1": area1_id, "area2": area2_id}, }, - headers=user_headers, ) assert res.status_code == 200, res.json() @@ -303,21 +261,14 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st json={ "weight": 1, "offset": 2, - "data": { - "area": area1_id, - "cluster": cluster_id, - }, - # NOTE: cluster_id in term data can be uppercase, but it must be lowercase in the returned ini configuration file + "data": {"area": area1_id, "cluster": cluster_id}, + # NOTE: cluster_id in term data can be uppercase, but it must be lowercase in the INI file }, - headers=user_headers, ) assert res.status_code == 200, res.json() # Get binding constraints list to check added terms - res = client.get( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id}", - headers=user_headers, - ) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}") assert res.status_code == 200, res.json() binding_constraint = res.json() constraint_terms = binding_constraint["terms"] @@ -340,19 +291,12 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st # Update constraint cluster term with uppercase cluster_id res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id}/term", - json={ - "id": f"{area1_id}.{cluster_id}", - "weight": 3, - }, - headers=user_headers, + json={"id": f"{area1_id}.{cluster_id}", "weight": 3}, ) assert res.status_code == 200, res.json() # Check updated terms, cluster_id should be lowercase in the returned configuration - res = client.get( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id}", - headers=user_headers, - ) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}") assert res.status_code == 200, res.json() binding_constraint = res.json() constraint_terms = binding_constraint["terms"] @@ -376,7 +320,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id}/term", json={"id": f"{area1_id}.!!invalid#cluster%%", "weight": 4}, - headers=user_headers, ) assert res.status_code == 404, res.json() exception = res.json()["exception"] @@ -388,11 +331,7 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st # Update constraint cluster term with empty data res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id}/term", - json={ - "id": f"{area1_id}.{cluster_id}", - "data": {}, - }, - headers=user_headers, + json={"id": f"{area1_id}.{cluster_id}", "data": {}}, ) assert res.status_code == 422, res.json() assert res.json() == { @@ -402,17 +341,11 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st } # Remove Constraint term - res = client.delete( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id}/term/{area1_id}%{area2_id}", - headers=user_headers, - ) + res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}/term/{area1_id}%{area2_id}") assert res.status_code == 200, res.json() # Check updated terms, the deleted term should no longer exist. - res = client.get( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id}", - headers=user_headers, - ) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}") assert res.status_code == 200, res.json() binding_constraint = res.json() constraint_terms = binding_constraint["terms"] @@ -427,17 +360,10 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st assert constraint_terms == expected # Update random field, shouldn't remove the term. - res = client.put( - f"v1/studies/{study_id}/bindingconstraints/{bc_id}", - json={"enabled": False}, - headers=user_headers, - ) + res = client.put(f"v1/studies/{study_id}/bindingconstraints/{bc_id}", json={"enabled": False}) assert res.status_code == 200, res.json() - res = client.get( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id}", - headers=user_headers, - ) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}") assert res.status_code == 200, res.json() binding_constraint = res.json() constraint_terms = binding_constraint["terms"] @@ -449,27 +375,19 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st # Update element of Binding constraint new_comment = "We made it !" - res = client.put( - f"v1/studies/{study_id}/bindingconstraints/{bc_id}", - json={"comments": new_comment}, - headers=user_headers, - ) + res = client.put(f"v1/studies/{study_id}/bindingconstraints/{bc_id}", json={"comments": new_comment}) assert res.status_code == 200 assert res.json()["comments"] == new_comment # The user change the timeStep to daily instead of hourly. # We must check that the matrix is a daily/weekly matrix. - res = client.put( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id}", - json={"timeStep": "daily"}, - headers=user_headers, - ) + res = client.put(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}", json={"timeStep": "daily"}) assert res.status_code == 200, res.json() assert res.json()["timeStep"] == "daily" # Check that the command corresponds to a change in `time_step` if study_type == "variant": - res = client.get(f"/v1/studies/{study_id}/commands", headers=user_headers) + res = client.get(f"/v1/studies/{study_id}/commands") commands = res.json() args = commands[-1]["args"] assert args["time_step"] == "daily" @@ -479,7 +397,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st res = client.get( f"/v1/studies/{study_id}/raw", params={"path": f"input/bindingconstraints/{bc_id}", "depth": 1, "formatted": True}, # type: ignore - headers=user_headers, ) assert res.status_code == 200, res.json() dataframe = res.json() @@ -501,7 +418,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "terms": [], "comments": "New API", }, - headers=user_headers, ) assert res.status_code == 400, res.json() assert res.json() == { @@ -520,7 +436,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "terms": [], "comments": "New API", }, - headers=user_headers, ) assert res.status_code == 400, res.json() assert res.json() == { @@ -539,7 +454,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "terms": [], "comments": "", }, - headers=user_headers, ) assert res.status_code == 409, res.json() @@ -556,7 +470,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "values": [[]], "less_term_matrix": [[]], }, - headers=user_headers, ) assert res.status_code == 422, res.json() description = res.json()["description"] @@ -577,7 +490,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "comments": "Incoherent matrix with version", "lessTermMatrix": [[]], }, - headers=user_headers, ) assert res.status_code == 422, res.json() description = res.json()["description"] @@ -594,11 +506,7 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st "comments": "Creation with matrix", "values": wrong_matrix.tolist(), } - res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", - json=wrong_request_args, - headers=user_headers, - ) + res = client.post(f"/v1/studies/{study_id}/bindingconstraints", json=wrong_request_args) assert res.status_code == 422, res.json() exception = res.json()["exception"] description = res.json()["description"] @@ -607,7 +515,7 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st assert "(366, 3)" in description # Delete a fake binding constraint - res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/fake_bc", headers=user_headers) + res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/fake_bc") assert res.status_code == 404, res.json() assert res.json()["exception"] == "BindingConstraintNotFound" assert res.json()["description"] == "Binding constraint 'fake_bc' not found" @@ -617,7 +525,6 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st res = client.put( f"/v1/studies/{study_id}/bindingconstraints/binding_constraint_2", json={"group": grp_name}, - headers=user_headers, ) assert res.status_code == 422, res.json() assert res.json()["exception"] == "InvalidFieldForVersionError" @@ -630,82 +537,48 @@ def test_lifecycle__nominal(self, client: TestClient, user_access_token: str, st res = client.put( f"/v1/studies/{study_id}/bindingconstraints/binding_constraint_2", json={"less_term_matrix": [[]]}, - headers=user_headers, ) assert res.status_code == 422, res.json() assert res.json()["exception"] == "InvalidFieldForVersionError" assert res.json()["description"] == "You cannot fill a 'matrix_term' as these values refer to v8.7+ studies" @pytest.mark.parametrize("study_type", ["raw", "variant"]) - def test_for_version_870(self, client: TestClient, admin_access_token: str, study_type: str) -> None: - admin_headers = {"Authorization": f"Bearer {admin_access_token}"} + def test_for_version_870(self, client: TestClient, user_access_token: str, study_type: str) -> None: + client.headers = {"Authorization": f"Bearer {user_access_token}"} # type: ignore # ============================= # STUDY PREPARATION # ============================= - res = client.post( - "/v1/studies", - headers=admin_headers, - params={"name": "foo"}, - ) + res = client.post("/v1/studies", params={"name": "foo"}) assert res.status_code == 201, res.json() study_id = res.json() if study_type == "variant": # Create Variant - res = client.post( - f"/v1/studies/{study_id}/variants", - headers=admin_headers, - params={"name": "Variant 1"}, - ) + res = client.post(f"/v1/studies/{study_id}/variants", params={"name": "Variant 1"}) assert res.status_code in {200, 201} study_id = res.json() # Create Areas - res = client.post( - f"/v1/studies/{study_id}/areas", - headers=admin_headers, - json={ - "name": "Area 1", - "type": "AREA", - }, - ) + res = client.post(f"/v1/studies/{study_id}/areas", json={"name": "Area 1", "type": "AREA"}) assert res.status_code == 200, res.json() area1_id = res.json()["id"] assert area1_id == "area 1" - res = client.post( - f"/v1/studies/{study_id}/areas", - headers=admin_headers, - json={ - "name": "Area 2", - "type": "AREA", - }, - ) + res = client.post(f"/v1/studies/{study_id}/areas", json={"name": "Area 2", "type": "AREA"}) assert res.status_code == 200, res.json() area2_id = res.json()["id"] assert area2_id == "area 2" # Create a link between the two areas - res = client.post( - f"/v1/studies/{study_id}/links", - headers=admin_headers, - json={ - "area1": area1_id, - "area2": area2_id, - }, - ) + res = client.post(f"/v1/studies/{study_id}/links", json={"area1": area1_id, "area2": area2_id}) assert res.status_code == 200, res.json() # Create a cluster in area1 res = client.post( f"/v1/studies/{study_id}/areas/{area1_id}/clusters/thermal", - headers=admin_headers, - json={ - "name": "Cluster 1", - "group": "Nuclear", - }, + json={"name": "Cluster 1", "group": "Nuclear"}, ) assert res.status_code == 200, res.json() cluster_id = res.json()["id"] @@ -718,11 +591,7 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud # Creation of a bc without group bc_id_wo_group = "binding_constraint_1" args = {"enabled": True, "timeStep": "hourly", "operator": "less", "terms": [], "comments": "New API"} - res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", - json={"name": bc_id_wo_group, **args}, - headers=admin_headers, - ) + res = client.post(f"/v1/studies/{study_id}/bindingconstraints", json={"name": bc_id_wo_group, **args}) assert res.status_code in {200, 201} assert res.json()["group"] == "default" @@ -731,7 +600,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.post( f"/v1/studies/{study_id}/bindingconstraints", json={"name": bc_id_w_group, "group": "specific_grp", **args}, - headers=admin_headers, ) assert res.status_code in {200, 201} assert res.json()["group"] == "specific_grp" @@ -742,12 +610,11 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.post( f"/v1/studies/{study_id}/bindingconstraints", json={"name": bc_id_w_matrix, "less_term_matrix": matrix_lt3.tolist(), **args}, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() if study_type == "variant": - res = client.get(f"/v1/studies/{study_id}/commands", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/commands") last_cmd_args = res.json()[-1]["args"] less_term_matrix = last_cmd_args["less_term_matrix"] equal_term_matrix = last_cmd_args["equal_term_matrix"] @@ -756,10 +623,10 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud # Check that raw matrices are created for term in ["lt", "gt", "eq"]: + path = f"input/bindingconstraints/{bc_id_w_matrix}_{term}" res = client.get( f"/v1/studies/{study_id}/raw", - params={"path": f"input/bindingconstraints/{bc_id_w_matrix}_{term}", "depth": 1, "formatted": True}, # type: ignore - headers=admin_headers, + params={"path": path, "depth": 1, "formatted": True}, # type: ignore ) assert res.status_code == 200, res.json() data = res.json()["data"] @@ -779,7 +646,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud {"weight": 1, "offset": 2, "data": {"area1": area1_id, "area2": area2_id}}, {"weight": 1, "offset": 2, "data": {"area": area1_id, "cluster": cluster_id}}, ], - headers=admin_headers, ) assert res.status_code == 200, res.json() @@ -787,7 +653,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.post( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}/terms", json=[{"weight": 1, "offset": 2}], - headers=admin_headers, ) assert res.status_code == 422, res.json() exception = res.json()["exception"] @@ -800,7 +665,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.post( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}/terms", json=[{"weight": 99, "offset": 0, "data": {"area1": area1_id, "area2": area2_id}}], - headers=admin_headers, ) assert res.status_code == 409, res.json() exception = res.json()["exception"] @@ -810,10 +674,7 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud assert f"{area1_id}%{area2_id}" in description, "Error message should contain the duplicate term ID" # Get binding constraints list to check added terms - res = client.get( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}", - headers=admin_headers, - ) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}") assert res.status_code == 200, res.json() binding_constraint = res.json() constraint_terms = binding_constraint["terms"] @@ -837,22 +698,22 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}/terms", json=[ - {"id": f"{area1_id}%{area2_id}", "weight": 4.4, "offset": 1}, + { + "id": f"{area1_id}%{area2_id}", + "weight": 4.4, + "offset": 1, + }, { "id": f"{area1_id}.{cluster_id}", "weight": 5.1, "data": {"area": area1_id, "cluster": cluster_id}, }, ], - headers=admin_headers, ) assert res.status_code == 200, res.json() # Asserts terms were updated - res = client.get( - f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}", - headers=admin_headers, - ) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}") assert res.status_code == 200, res.json() binding_constraint = res.json() constraint_terms = binding_constraint["terms"] @@ -881,7 +742,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_matrix}", json={"group": grp_name}, - headers=admin_headers, ) assert res.status_code == 200, res.json() assert res.json()["group"] == grp_name @@ -890,14 +750,12 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_matrix}", json={"greater_term_matrix": matrix_lt3.tolist()}, - headers=admin_headers, ) assert res.status_code == 200, res.json() res = client.get( f"/v1/studies/{study_id}/raw", params={"path": f"input/bindingconstraints/{bc_id_w_matrix}_gt"}, - headers=admin_headers, ) assert res.status_code == 200, res.json() assert res.json()["data"] == matrix_lt3.tolist() @@ -907,13 +765,12 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_matrix}", json={"timeStep": "daily"}, - headers=admin_headers, ) assert res.status_code == 200, res.json() if study_type == "variant": # Check the last command is a change on `time_step` field only - res = client.get(f"/v1/studies/{study_id}/commands", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/commands") commands = res.json() command_args = commands[-1]["args"] assert command_args["time_step"] == "daily" @@ -935,7 +792,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud "depth": 1, "formatted": True, }, # type: ignore - headers=admin_headers, ) assert res.status_code == 200, res.json() assert res.json()["data"] == expected_matrix.tolist() @@ -945,11 +801,11 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud # ============================= # Delete a binding constraint - res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}", headers=admin_headers) + res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_group}") assert res.status_code == 200, res.json() # Asserts that the deletion worked - res = client.get(f"/v1/studies/{study_id}/bindingconstraints", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/bindingconstraints") assert len(res.json()) == 2 # ============================= @@ -968,7 +824,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud "comments": "New API", "values": [[]], }, - headers=admin_headers, ) assert res.status_code == 422, res.json() assert res.json()["description"] == "You cannot fill 'values' as it refers to the matrix before v8.7" @@ -977,7 +832,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{bc_id_w_matrix}", json={"values": [[]]}, - headers=admin_headers, ) assert res.status_code == 422, res.json() assert res.json()["exception"] == "InvalidFieldForVersionError" @@ -995,7 +849,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud "greater_term_matrix": matrix_gt2.tolist(), **args, }, - headers=admin_headers, ) assert res.status_code == 422, res.json() exception = res.json()["exception"] @@ -1020,7 +873,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud "group": "Group 1", **args, }, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() first_bc_id = res.json()["id"] @@ -1029,17 +881,13 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud random_matrix = pd.DataFrame(generator.integers(0, 10, size=(4, 1))) _upload_matrix( client, - admin_access_token, study_id, f"input/bindingconstraints/{first_bc_id}_gt", random_matrix, ) # Validation should fail - res = client.get( - f"/v1/studies/{study_id}/constraint-groups/Group 1/validate", - headers=admin_headers, - ) + res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 1/validate") assert res.status_code == 422 obj = res.json() assert obj["exception"] == "WrongMatrixHeightError" @@ -1049,7 +897,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{first_bc_id}", json={"greater_term_matrix": matrix_lt3.tolist()}, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() @@ -1059,10 +906,7 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud # # Asserts everything is ok. - res = client.get( - f"/v1/studies/{study_id}/constraint-groups/Group 1/validate", - headers=admin_headers, - ) + res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 1/validate") assert res.status_code == 200, res.json() matrix_gt4 = np.ones((8784, 4)) # Wrong number of columns @@ -1074,13 +918,12 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud "group": "group 1", # Same group, but different case **args, }, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() second_bc_id = res.json()["id"] # validate the BC group "Group 1" - res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 1/validate", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 1/validate") assert res.status_code == 422, res.json() assert res.json()["exception"] == "MatrixWidthMismatchError" description = res.json()["description"] @@ -1091,7 +934,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{second_bc_id}", json={"greater_term_matrix": matrix_lt3.tolist()}, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() @@ -1111,7 +953,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud "group": "Group 2", **args, }, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() third_bd_id = res.json()["id"] @@ -1119,13 +960,12 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"v1/studies/{study_id}/bindingconstraints/{third_bd_id}", json={"group": "Group 1"}, - headers=admin_headers, ) # This should succeed but cause the validation endpoint to fail. assert res.status_code in {200, 201}, res.json() # validate the BC group "Group 1" - res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 1/validate", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 1/validate") assert res.status_code == 422, res.json() assert res.json()["exception"] == "MatrixWidthMismatchError" description = res.json()["description"] @@ -1136,7 +976,6 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"/v1/studies/{study_id}/bindingconstraints/{third_bd_id}", json={"greater_term_matrix": matrix_lt3.tolist()}, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() @@ -1149,24 +988,22 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud res = client.put( f"v1/studies/{study_id}/bindingconstraints/{second_bc_id}", json={"group": "Group 2"}, - headers=admin_headers, ) assert res.status_code in {200, 201}, res.json() # validate the "Group 2": for the moment the BC is valid - res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 2/validate", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/constraint-groups/Group 2/validate") assert res.status_code in {200, 201}, res.json() res = client.put( f"v1/studies/{study_id}/bindingconstraints/{second_bc_id}", json={"greater_term_matrix": matrix_gt4.tolist()}, - headers=admin_headers, ) # This should succeed but cause the validation endpoint to fail. assert res.status_code in {200, 201}, res.json() # Collect all the binding constraints groups - res = client.get(f"/v1/studies/{study_id}/constraint-groups", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/constraint-groups") assert res.status_code in {200, 201}, res.json() groups = res.json() assert set(groups) == {"default", "random_grp", "Group 1", "Group 2"} @@ -1186,7 +1023,7 @@ def test_for_version_870(self, client: TestClient, admin_access_token: str, stud ] # Validate all binding constraints groups - res = client.get(f"/v1/studies/{study_id}/constraint-groups/validate-all", headers=admin_headers) + res = client.get(f"/v1/studies/{study_id}/constraint-groups/validate-all") assert res.status_code == 422, res.json() exception = res.json()["exception"] description = res.json()["description"] diff --git a/tests/storage/repository/filesystem/matrix/input_series_matrix_test.py b/tests/storage/repository/filesystem/matrix/input_series_matrix_test.py deleted file mode 100644 index a422c43f8d..0000000000 --- a/tests/storage/repository/filesystem/matrix/input_series_matrix_test.py +++ /dev/null @@ -1,42 +0,0 @@ -from pathlib import Path -from unittest.mock import Mock - -from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig -from antarest.study.storage.rawstudy.model.filesystem.matrix.input_series_matrix import InputSeriesMatrix - - -def test_get(tmp_path: Path) -> None: - file = tmp_path / "input.txt" - content = """ -100000 100000 0.010000 0.010000 0 0 0 0 -100000 100000 0.010000 0.010000 0 0 0 0 - """ - file.write_text(content) - - config = FileStudyTreeConfig(study_path=file, path=file, version=-1, study_id="id") - node = InputSeriesMatrix(context=Mock(), config=config, nb_columns=8) - - assert node.load() == { - "columns": [0, 1, 2, 3, 4, 5, 6, 7], - "data": [ - [100000.0, 100000.0, 0.01, 0.01, 0.0, 0.0, 0.0, 0.0], - [100000.0, 100000.0, 0.01, 0.01, 0.0, 0.0, 0.0, 0.0], - ], - "index": [0, 1], - } - - -def test_save(tmp_path: Path) -> None: - file = tmp_path / "input.txt" - file.write_text("\n") - - config = FileStudyTreeConfig(study_path=file, path=file, study_id="id", version=-1) - node = InputSeriesMatrix(context=Mock(), config=config) - - node.dump({"columns": [0, 1], "data": [[1, 2], [3, 4]], "index": [0, 1]}) - assert ( - file.read_text() - == """1\t2 -3\t4 -""" - ) diff --git a/tests/storage/repository/filesystem/matrix/output_series_matrix_test.py b/tests/storage/repository/filesystem/matrix/output_series_matrix_test.py deleted file mode 100644 index d739e73b0d..0000000000 --- a/tests/storage/repository/filesystem/matrix/output_series_matrix_test.py +++ /dev/null @@ -1,91 +0,0 @@ -from pathlib import Path -from unittest.mock import Mock - -import pandas as pd - -from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig -from antarest.study.storage.rawstudy.model.filesystem.matrix.head_writer import AreaHeadWriter -from antarest.study.storage.rawstudy.model.filesystem.matrix.matrix import MatrixFrequency -from antarest.study.storage.rawstudy.model.filesystem.matrix.output_series_matrix import OutputSeriesMatrix - -MATRIX_DAILY_DATA = """\ -DE\tarea\tva\thourly -\tVARIABLES\tBEGIN\tEND -\t2\t1\t2 - -DE\thourly\t\t\t\t01_solar\t02_wind_on -\t\t\t\t\tMWh\tMWh -\tindex\tday\tmonth\thourly\tEXP\tEXP -\t1\t1\tJAN\t00:00\t27000\t600 -\t2\t1\tJAN\t01:00\t48000\t34400 -""" - - -def test_get(tmp_path: Path) -> None: - file = tmp_path / "matrix-daily.txt" - file.write_text("\n\n\n\nmock\tfile\ndummy\tdummy\ndummy\tdummy\ndummy\tdummy") - config = FileStudyTreeConfig(study_path=file, path=file, study_id="id", version=-1) - - serializer = Mock() - serializer.extract_date.return_value = ( - pd.Index(["01/02", "01/01"]), - pd.DataFrame( - data={ - ("01_solar", "MWh", "EXP"): [27000, 48000], - ("02_wind_on", "MWh", "EXP"): [600, 34400], - } - ), - ) - - matrix = pd.DataFrame( - data={ - ("01_solar", "MWh", "EXP"): [27000, 48000], - ("02_wind_on", "MWh", "EXP"): [600, 34400], - }, - index=["01/02", "01/01"], - ) - - node = OutputSeriesMatrix( - context=Mock(), - config=config, - freq=MatrixFrequency.DAILY, - date_serializer=serializer, - head_writer=AreaHeadWriter(area="", data_type="", freq=""), - ) - assert node.load() == matrix.to_dict(orient="split") - - -def test_save(tmp_path: Path) -> None: - file = tmp_path / "matrix-daily.txt" - config = FileStudyTreeConfig(study_path=file, path=file, study_id="id", version=-1) - - serializer = Mock() - serializer.build_date.return_value = pd.DataFrame( - { - 0: ["DE", "", "", "", ""], - 1: ["hourly", "", "index", 1, 2], - 2: ["", "", "day", "1", "1"], - 3: ["", "", "month", "JAN", "JAN"], - 4: ["", "", "hourly", "00:00", "01:00"], - } - ) - - node = OutputSeriesMatrix( - context=Mock(), - config=config, - freq=MatrixFrequency.DAILY, - date_serializer=serializer, - head_writer=AreaHeadWriter(area="de", data_type="va", freq="hourly"), - ) - - matrix = pd.DataFrame( - data={ - ("01_solar", "MWh", "EXP"): [27000, 48000], - ("02_wind_on", "MWh", "EXP"): [600, 34400], - }, - index=["01/01", "01/02"], - ) - - node.dump(matrix.to_dict(orient="split")) - actual = file.read_text() - assert actual == MATRIX_DAILY_DATA diff --git a/tests/storage/repository/filesystem/matrix/date_serializer_test.py b/tests/storage/repository/filesystem/matrix/test_date_serializer.py similarity index 100% rename from tests/storage/repository/filesystem/matrix/date_serializer_test.py rename to tests/storage/repository/filesystem/matrix/test_date_serializer.py diff --git a/tests/storage/repository/filesystem/matrix/head_writer_test.py b/tests/storage/repository/filesystem/matrix/test_head_writer.py similarity index 100% rename from tests/storage/repository/filesystem/matrix/head_writer_test.py rename to tests/storage/repository/filesystem/matrix/test_head_writer.py diff --git a/tests/storage/repository/filesystem/matrix/test_input_series_matrix.py b/tests/storage/repository/filesystem/matrix/test_input_series_matrix.py new file mode 100644 index 0000000000..6b7bcbaa01 --- /dev/null +++ b/tests/storage/repository/filesystem/matrix/test_input_series_matrix.py @@ -0,0 +1,94 @@ +import textwrap +import typing as t +from pathlib import Path +from unittest.mock import Mock + +import pytest + +from antarest.matrixstore.service import ISimpleMatrixService +from antarest.matrixstore.uri_resolver_service import UriResolverService +from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig +from antarest.study.storage.rawstudy.model.filesystem.context import ContextServer +from antarest.study.storage.rawstudy.model.filesystem.folder_node import ChildNotFoundError +from antarest.study.storage.rawstudy.model.filesystem.matrix.input_series_matrix import InputSeriesMatrix + + +class TestInputSeriesMatrix: + @pytest.fixture(name="my_study_config") + def fixture_my_study_config(self, tmp_path: Path) -> FileStudyTreeConfig: + """ + Construct a FileStudyTreeConfig object for a dummy study stored in a temporary directory. + """ + return FileStudyTreeConfig( + study_path=tmp_path, + path=tmp_path / "input.txt", + study_id="df0a8aa9-6c6f-4e8b-a84e-45de2fb29cd3", + version=800, + ) + + def test_load(self, my_study_config: FileStudyTreeConfig) -> None: + file = my_study_config.path + content = textwrap.dedent( + """\ + 100000\t100000\t0.010000\t0.010000\t0\t0\t0\t3.14 + 100000\t100000\t0.010000\t0.010000\t0\t0\t0\t6.28 + """ + ) + file.write_text(content) + + node = InputSeriesMatrix(context=Mock(), config=my_study_config, nb_columns=8) + actual = node.load() + expected = { + "columns": [0, 1, 2, 3, 4, 5, 6, 7], + "data": [ + [100000.0, 100000.0, 0.01, 0.01, 0.0, 0.0, 0.0, 3.14], + [100000.0, 100000.0, 0.01, 0.01, 0.0, 0.0, 0.0, 6.28], + ], + "index": [0, 1], + } + assert actual == expected + + def test_load__file_not_found(self, my_study_config: FileStudyTreeConfig) -> None: + node = InputSeriesMatrix(context=Mock(), config=my_study_config) + with pytest.raises(ChildNotFoundError) as ctx: + node.load() + err_msg = str(ctx.value) + assert "input.txt" in err_msg + assert my_study_config.study_id in err_msg + assert "not found" in err_msg.lower() + + def test_load__link_to_matrix(self, my_study_config: FileStudyTreeConfig) -> None: + link = my_study_config.path.with_suffix(".txt.link") + matrix_uri = "matrix://54e252eb14c0440055c82520c338376ff436e1d7ed6cb7283084c89e2e472c42" + matrix_obj = { + "data": [[1, 2], [3, 4]], + "index": [0, 1], + "columns": [0, 1], + } + link.write_text(matrix_uri) + + def resolve(uri: str, formatted: bool = True) -> t.Dict[str, t.Any]: + assert uri == matrix_uri + assert formatted is True + return matrix_obj + + context = ContextServer( + matrix=Mock(spec=ISimpleMatrixService), + resolver=Mock(spec=UriResolverService, resolve=resolve), + ) + + node = InputSeriesMatrix(context=context, config=my_study_config) + actual = node.load() + assert actual == matrix_obj + + def test_save(self, my_study_config: FileStudyTreeConfig) -> None: + node = InputSeriesMatrix(context=Mock(), config=my_study_config) + node.dump({"columns": [0, 1], "data": [[1, 2], [3, 4]], "index": [0, 1]}) + actual = my_study_config.path.read_text() + expected = textwrap.dedent( + """\ + 1\t2 + 3\t4 + """ + ) + assert actual == expected diff --git a/tests/storage/repository/filesystem/matrix/test_output_series_matrix.py b/tests/storage/repository/filesystem/matrix/test_output_series_matrix.py new file mode 100644 index 0000000000..c93f999627 --- /dev/null +++ b/tests/storage/repository/filesystem/matrix/test_output_series_matrix.py @@ -0,0 +1,116 @@ +from pathlib import Path +from unittest.mock import Mock + +import pandas as pd +import pytest + +from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig +from antarest.study.storage.rawstudy.model.filesystem.folder_node import ChildNotFoundError +from antarest.study.storage.rawstudy.model.filesystem.matrix.head_writer import AreaHeadWriter +from antarest.study.storage.rawstudy.model.filesystem.matrix.matrix import MatrixFrequency +from antarest.study.storage.rawstudy.model.filesystem.matrix.output_series_matrix import OutputSeriesMatrix + +MATRIX_DAILY_DATA = """\ +DE\tarea\tva\thourly +\tVARIABLES\tBEGIN\tEND +\t2\t1\t2 + +DE\thourly\t\t\t\t01_solar\t02_wind_on +\t\t\t\t\tMWh\tMWh +\tindex\tday\tmonth\thourly\tEXP\tEXP +\t1\t1\tJAN\t00:00\t27000\t600 +\t2\t1\tJAN\t01:00\t48000\t34400 +""" + + +class TestOutputSeriesMatrix: + @pytest.fixture(name="my_study_config") + def fixture_my_study_config(self, tmp_path: Path) -> FileStudyTreeConfig: + """ + Construct a FileStudyTreeConfig object for a dummy study stored in a temporary directory. + """ + return FileStudyTreeConfig( + study_path=tmp_path, + path=tmp_path / "matrix-daily.txt", + study_id="df0a8aa9-6c6f-4e8b-a84e-45de2fb29cd3", + version=800, + ) + + def test_load(self, my_study_config: FileStudyTreeConfig) -> None: + file = my_study_config.path + file.write_text("\n\n\n\nmock\tfile\ndummy\tdummy\ndummy\tdummy\ndummy\tdummy") + + serializer = Mock() + serializer.extract_date.return_value = ( + pd.Index(["01/02", "01/01"]), + pd.DataFrame( + data={ + ("01_solar", "MWh", "EXP"): [27000, 48000], + ("02_wind_on", "MWh", "EXP"): [600, 34400], + } + ), + ) + + matrix = pd.DataFrame( + data={ + ("01_solar", "MWh", "EXP"): [27000, 48000], + ("02_wind_on", "MWh", "EXP"): [600, 34400], + }, + index=["01/02", "01/01"], + ) + + node = OutputSeriesMatrix( + context=Mock(), + config=my_study_config, + freq=MatrixFrequency.DAILY, + date_serializer=serializer, + head_writer=AreaHeadWriter(area="", data_type="", freq=""), + ) + assert node.load() == matrix.to_dict(orient="split") + + def test_load__file_not_found(self, my_study_config: FileStudyTreeConfig) -> None: + node = OutputSeriesMatrix( + context=Mock(), + config=my_study_config, + freq=MatrixFrequency.DAILY, + date_serializer=Mock(), + head_writer=AreaHeadWriter(area="", data_type="", freq=""), + ) + with pytest.raises(ChildNotFoundError) as ctx: + node.load() + err_msg = str(ctx.value) + assert "'matrix-daily.txt" in err_msg + assert my_study_config.study_id in err_msg + assert "not found" in err_msg.lower() + + def test_save(self, my_study_config: FileStudyTreeConfig) -> None: + serializer = Mock() + serializer.build_date.return_value = pd.DataFrame( + { + 0: ["DE", "", "", "", ""], + 1: ["hourly", "", "index", 1, 2], + 2: ["", "", "day", "1", "1"], + 3: ["", "", "month", "JAN", "JAN"], + 4: ["", "", "hourly", "00:00", "01:00"], + } + ) + + node = OutputSeriesMatrix( + context=Mock(), + config=my_study_config, + freq=MatrixFrequency.DAILY, + date_serializer=serializer, + head_writer=AreaHeadWriter(area="de", data_type="va", freq="hourly"), + ) + + matrix = pd.DataFrame( + data={ + ("01_solar", "MWh", "EXP"): [27000, 48000], + ("02_wind_on", "MWh", "EXP"): [600, 34400], + }, + index=["01/01", "01/02"], + ) + + node.dump(matrix.to_dict(orient="split")) # type: ignore + actual = my_study_config.path.read_text() + assert actual == MATRIX_DAILY_DATA From af28e8d23e17334e0f1df486463ec3fdab7f9fbc Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE <43534797+laurent-laporte-pro@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:56:18 +0200 Subject: [PATCH 08/17] ci: update Actions in GitHub workflows (#2080) --- .github/workflows/compatibility.yml | 50 ----------------------------- .github/workflows/deploy.yml | 2 +- .github/workflows/main.yml | 2 +- 3 files changed, 2 insertions(+), 52 deletions(-) delete mode 100644 .github/workflows/compatibility.yml diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml deleted file mode 100644 index 25d2506003..0000000000 --- a/.github/workflows/compatibility.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: compatibility -on: - push: - branches: - - "compatibility" - -jobs: - python-test: - runs-on: ${{ matrix.os }} - strategy: - max-parallel: 9 - matrix: - os: [windows-latest, ubuntu-20.04, macOS-latest] - python-version: [3.8] - - steps: - - name: Checkout github repo - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements-dev.txt - - name: Test with pytest - run: | - pytest - - npm-test: - runs-on: ${{ matrix.os }} - strategy: - max-parallel: 9 - matrix: - os: [windows-latest, ubuntu-20.04, macOS-latest] - node-version: [18.16.1] - steps: - - name: Checkout github repo - uses: actions/checkout@v4 - - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - name: Install dependencies - run: npm install - working-directory: webapp - - name: Build - run: npm run build - working-directory: webapp diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 86eba91403..e91a2a0b65 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -24,7 +24,7 @@ jobs: run: choco install wget --no-progress - name: 💚 Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18.16.1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 087221fa3c..fd2a6ddff9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -74,7 +74,7 @@ jobs: - name: Checkout github repo uses: actions/checkout@v4 - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18.16.1 - name: Install dependencies From 44d1057fa55adfa1b1b8f34cd7eab0195efa8e8b Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE <43534797+laurent-laporte-pro@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:42:24 +0200 Subject: [PATCH 09/17] test: rename 'study_id' fixture to 'internal_study_id' to avoid confusion with `study_id` variable (#2079) --- tests/integration/conftest.py | 6 +- .../test_aggregate_raw_data.py | 28 +++-- .../test_download_matrices.py | 22 ++-- .../test_fetch_raw_data.py | 36 +++--- .../studies_blueprint/test_comments.py | 14 +-- .../studies_blueprint/test_disk_usage.py | 6 +- .../test_study_matrix_index.py | 12 +- .../studies_blueprint/test_synthesis.py | 10 +- .../studies_blueprint/test_update_tags.py | 16 +-- .../test_advanced_parameters.py | 12 +- .../test_config_general.py | 8 +- .../study_data_blueprint/test_edit_matrix.py | 8 +- .../test_hydro_allocation.py | 32 ++--- .../test_hydro_correlation.py | 36 +++--- .../test_hydro_inflow_structure.py | 16 +-- .../study_data_blueprint/test_renewable.py | 60 +++++----- .../study_data_blueprint/test_st_storage.py | 72 +++++------ .../study_data_blueprint/test_table_mode.py | 44 +++---- .../study_data_blueprint/test_thermal.py | 112 +++++++++--------- tests/integration/test_integration.py | 54 +++++---- tests/integration/test_studies_upgrade.py | 14 ++- .../test_renewable_cluster.py | 36 +++--- .../variant_blueprint/test_st_storage.py | 20 ++-- .../variant_blueprint/test_thermal_cluster.py | 4 +- 24 files changed, 343 insertions(+), 335 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 0ac1e1763f..64d00e745d 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -120,12 +120,12 @@ def user_access_token_fixture( return t.cast(str, credentials["access_token"]) -@pytest.fixture(name="study_id") -def study_id_fixture( +@pytest.fixture(name="internal_study_id") +def internal_study_fixture( client: TestClient, user_access_token: str, ) -> str: - """Get the ID of the study stored in database""" + """Get the ID of the internal study which is scanned by the watcher""" res = client.get( "/v1/studies", headers={"Authorization": f"Bearer {user_access_token}"}, diff --git a/tests/integration/raw_studies_blueprint/test_aggregate_raw_data.py b/tests/integration/raw_studies_blueprint/test_aggregate_raw_data.py index 70cad9cd28..1dd53fdfe2 100644 --- a/tests/integration/raw_studies_blueprint/test_aggregate_raw_data.py +++ b/tests/integration/raw_studies_blueprint/test_aggregate_raw_data.py @@ -193,7 +193,7 @@ def test_area_aggregation( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """ Test the aggregation of areas data @@ -202,7 +202,7 @@ def test_area_aggregation( for params, expected_result_filename in AREAS_REQUESTS: output_id = params.pop("output_id") - res = client.get(f"/v1/studies/{study_id}/areas/aggregate/{output_id}", params=params) + res = client.get(f"/v1/studies/{internal_study_id}/areas/aggregate/{output_id}", params=params) assert res.status_code == 200, res.json() content = io.BytesIO(res.content) df = pd.read_csv(content, index_col=0, sep=",") @@ -222,7 +222,7 @@ def test_links_aggregation( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """ Test the aggregation of links data @@ -231,7 +231,7 @@ def test_links_aggregation( for params, expected_result_filename in LINKS_REQUESTS: output_id = params.pop("output_id") - res = client.get(f"/v1/studies/{study_id}/links/aggregate/{output_id}", params=params) + res = client.get(f"/v1/studies/{internal_study_id}/links/aggregate/{output_id}", params=params) assert res.status_code == 200, res.json() content = io.BytesIO(res.content) df = pd.read_csv(content, index_col=0, sep=",") @@ -251,7 +251,7 @@ def test_different_formats( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """ Tests that all formats work and produce the same result @@ -260,7 +260,7 @@ def test_different_formats( for params, expected_result_filename in SAME_REQUEST_DIFFERENT_FORMATS: output_id = params.pop("output_id") - res = client.get(f"/v1/studies/{study_id}/links/aggregate/{output_id}", params=params) + res = client.get(f"/v1/studies/{internal_study_id}/links/aggregate/{output_id}", params=params) assert res.status_code == 200, res.json() content = io.BytesIO(res.content) export_format = params["format"] @@ -282,31 +282,33 @@ def test_different_formats( expected_df[col] = expected_df[col].astype(df[col].dtype) pd.testing.assert_frame_equal(df, expected_df) - def test_aggregation_with_incoherent_bodies(self, client: TestClient, user_access_token: str, study_id: str): + def test_aggregation_with_incoherent_bodies( + self, client: TestClient, user_access_token: str, internal_study_id: str + ): """ Asserts that requests with incoherent bodies don't crash but send empty dataframes """ client.headers = {"Authorization": f"Bearer {user_access_token}"} for params in INCOHERENT_REQUESTS_BODIES: output_id = params.pop("output_id") - res = client.get(f"/v1/studies/{study_id}/links/aggregate/{output_id}", params=params) + res = client.get(f"/v1/studies/{internal_study_id}/links/aggregate/{output_id}", params=params) assert res.status_code == 200, res.json() content = io.BytesIO(res.content) df = pd.read_csv(content, index_col=0, sep=",") assert df.empty - def test_wrongly_typed_request(self, client: TestClient, user_access_token: str, study_id: str): + def test_wrongly_typed_request(self, client: TestClient, user_access_token: str, internal_study_id: str): """ Asserts that wrongly typed requests send an HTTP 422 Exception """ client.headers = {"Authorization": f"Bearer {user_access_token}"} for params in WRONGLY_TYPED_REQUESTS: output_id = params.pop("output_id") - res = client.get(f"/v1/studies/{study_id}/links/aggregate/{output_id}", params=params) + res = client.get(f"/v1/studies/{internal_study_id}/links/aggregate/{output_id}", params=params) assert res.status_code == 422 assert res.json()["exception"] == "RequestValidationError" - def test_aggregation_with_wrong_output(self, client: TestClient, user_access_token: str, study_id: str): + def test_aggregation_with_wrong_output(self, client: TestClient, user_access_token: str, internal_study_id: str): """ Asserts that requests with wrong output send an HTTP 422 Exception """ @@ -314,7 +316,7 @@ def test_aggregation_with_wrong_output(self, client: TestClient, user_access_tok # test for areas res = client.get( - f"/v1/studies/{study_id}/areas/aggregate/unknown_id", + f"/v1/studies/{internal_study_id}/areas/aggregate/unknown_id", params={ "query_file": AreasQueryFile.VALUES, "frequency": MatrixFrequency.HOURLY, @@ -326,7 +328,7 @@ def test_aggregation_with_wrong_output(self, client: TestClient, user_access_tok # test for links res = client.get( - f"/v1/studies/{study_id}/links/aggregate/unknown_id", + f"/v1/studies/{internal_study_id}/links/aggregate/unknown_id", params={ "query_file": LinksQueryFile.VALUES, "frequency": MatrixFrequency.HOURLY, diff --git a/tests/integration/raw_studies_blueprint/test_download_matrices.py b/tests/integration/raw_studies_blueprint/test_download_matrices.py index d2430c5bf0..0f4e764089 100644 --- a/tests/integration/raw_studies_blueprint/test_download_matrices.py +++ b/tests/integration/raw_studies_blueprint/test_download_matrices.py @@ -45,13 +45,13 @@ def copy_upgrade_study(self, ref_study_id, target_version=820): assert task.status == TaskStatus.COMPLETED return study_820_id - def upload_matrix(self, study_id: str, matrix_path: str, df: pd.DataFrame) -> None: + def upload_matrix(self, internal_study_id: str, matrix_path: str, df: pd.DataFrame) -> None: tsv = io.BytesIO() df.to_csv(tsv, sep="\t", index=False, header=False) tsv.seek(0) # noinspection SpellCheckingInspection res = self.client.put( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": matrix_path, "create_missing": True}, headers=self.headers, files={"file": tsv, "create_missing": "true"}, @@ -92,9 +92,9 @@ def create_area(self, parent_id, *, name: str, country: str = "FR") -> str: area_id = res.json()["id"] return area_id - def update_general_data(self, study_id: str, **data: t.Any): + def update_general_data(self, internal_study_id: str, **data: t.Any): res = self.client.put( - f"/v1/studies/{study_id}/config/general/form", + f"/v1/studies/{internal_study_id}/config/general/form", json=data, headers=self.headers, ) @@ -107,7 +107,7 @@ class TestDownloadMatrices: Checks the retrieval of matrices with the endpoint GET studies/uuid/raw/download """ - def test_download_matrices(self, client: TestClient, user_access_token: str, study_id: str) -> None: + def test_download_matrices(self, client: TestClient, user_access_token: str, internal_study_id: str) -> None: user_headers = {"Authorization": f"Bearer {user_access_token}"} # ===================== @@ -116,7 +116,7 @@ def test_download_matrices(self, client: TestClient, user_access_token: str, stu preparer = PreparerProxy(client, user_access_token) - study_820_id = preparer.copy_upgrade_study(study_id, target_version=820) + study_820_id = preparer.copy_upgrade_study(internal_study_id, target_version=820) # Create Variant variant_id = preparer.create_variant(study_820_id, name="New Variant") @@ -131,7 +131,7 @@ def test_download_matrices(self, client: TestClient, user_access_token: str, stu preparer.generate_snapshot(variant_id) # Prepare a managed study to test specific matrices for version 8.6 - study_860_id = preparer.copy_upgrade_study(study_id, target_version=860) + study_860_id = preparer.copy_upgrade_study(internal_study_id, target_version=860) # Import a Min Gen. matrix: shape=(8760, 3), with random integers between 0 and 1000 generator = np.random.default_rng(11) @@ -226,7 +226,7 @@ def test_download_matrices(self, client: TestClient, user_access_token: str, stu # tests links headers before v8.2 res = client.get( - f"/v1/studies/{study_id}/raw/download", + f"/v1/studies/{internal_study_id}/raw/download", params={"path": "input/links/de/fr", "format": "tsv", "index": False}, headers=user_headers, ) @@ -275,7 +275,7 @@ def test_download_matrices(self, client: TestClient, user_access_token: str, stu # test for empty matrix res = client.get( - f"/v1/studies/{study_id}/raw/download", + f"/v1/studies/{internal_study_id}/raw/download", params={"path": "input/hydro/common/capacity/waterValues_de", "format": "tsv"}, headers=user_headers, ) @@ -305,7 +305,7 @@ def test_download_matrices(self, client: TestClient, user_access_token: str, stu # asserts endpoint returns the right columns for output matrix res = client.get( - f"/v1/studies/{study_id}/raw/download", + f"/v1/studies/{internal_study_id}/raw/download", params={ "path": "output/20201014-1422eco-hello/economy/mc-ind/00001/links/de/fr/values-hourly", "format": "tsv", @@ -331,7 +331,7 @@ def test_download_matrices(self, client: TestClient, user_access_token: str, stu # test energy matrix to test the regex res = client.get( - f"/v1/studies/{study_id}/raw/download", + f"/v1/studies/{internal_study_id}/raw/download", params={"path": "input/hydro/prepro/de/energy", "format": "tsv"}, headers=user_headers, ) diff --git a/tests/integration/raw_studies_blueprint/test_fetch_raw_data.py b/tests/integration/raw_studies_blueprint/test_fetch_raw_data.py index 8229fa543a..e55929c97a 100644 --- a/tests/integration/raw_studies_blueprint/test_fetch_raw_data.py +++ b/tests/integration/raw_studies_blueprint/test_fetch_raw_data.py @@ -25,7 +25,7 @@ def test_get_study( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """ Test the `get_study` endpoint for fetching raw data from a study. @@ -42,7 +42,7 @@ def test_get_study( """ # First copy the user resources in the Study directory with db(): - study: RawStudy = db.session.get(Study, study_id) + study: RawStudy = db.session.get(Study, internal_study_id) study_dir = pathlib.Path(study.path) headers = {"Authorization": f"Bearer {user_access_token}"} @@ -57,7 +57,7 @@ def test_get_study( for file_path in user_folder_dir.glob("*.*"): rel_path = file_path.relative_to(study_dir).as_posix() res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": rel_path, "depth": 1}, headers=headers, ) @@ -83,7 +83,7 @@ def test_get_study( for file_path in user_folder_dir.glob("*.*"): rel_path = file_path.relative_to(study_dir) res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": f"/{rel_path.as_posix()}", "depth": 1}, headers=headers, ) @@ -94,7 +94,7 @@ def test_get_study( # If you try to retrieve a file that doesn't exist, we should have a 404 error res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "user/somewhere/something.txt"}, headers=headers, ) @@ -107,7 +107,7 @@ def test_get_study( # If you want to update an existing resource, you can use PUT method. # But, if the resource doesn't exist, you should have a 404 Not Found error. res = client.put( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "user/somewhere/something.txt"}, headers=headers, files={"file": io.BytesIO(b"Goodbye World!")}, @@ -121,7 +121,7 @@ def test_get_study( # To create a resource, you can use PUT method and the `create_missing` flag. # The expected status code should be 204 No Content. res = client.put( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "user/somewhere/something.txt", "create_missing": True}, headers=headers, files={"file": io.BytesIO(b"Goodbye Cruel World!")}, @@ -131,7 +131,7 @@ def test_get_study( # To update a resource, you can use PUT method, with or without the `create_missing` flag. # The expected status code should be 204 No Content. res = client.put( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "user/somewhere/something.txt", "create_missing": True}, headers=headers, files={"file": io.BytesIO(b"This is the end!")}, @@ -140,7 +140,7 @@ def test_get_study( # You can check that the resource has been created or updated. res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "user/somewhere/something.txt"}, headers=headers, ) @@ -150,7 +150,7 @@ def test_get_study( # If we ask for properties, we should have a JSON content rel_path = "/input/links/de/properties/fr" res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": rel_path, "depth": 2}, headers=headers, ) @@ -175,7 +175,7 @@ def test_get_study( # If we ask for a matrix, we should have a JSON content if formatted is True rel_path = "/input/links/de/fr" res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": rel_path, "formatted": True}, headers=headers, ) @@ -186,7 +186,7 @@ def test_get_study( # If we ask for a matrix, we should have a CSV content if formatted is False rel_path = "/input/links/de/fr" res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": rel_path, "formatted": False}, headers=headers, ) @@ -198,7 +198,7 @@ def test_get_study( # If ask for an empty matrix, we should have an empty binary content res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "input/thermal/prepro/de/01_solar/data", "formatted": False}, headers=headers, ) @@ -207,7 +207,7 @@ def test_get_study( # But, if we use formatted = True, we should have a JSON objet representing and empty matrix res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "input/thermal/prepro/de/01_solar/data", "formatted": True}, headers=headers, ) @@ -219,7 +219,7 @@ def test_get_study( for file_path in user_folder_dir.glob("*.*"): rel_path = file_path.relative_to(study_dir) res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": f"/{rel_path.as_posix()}", "depth": 1}, headers=headers, ) @@ -228,7 +228,7 @@ def test_get_study( # We can access to the configuration the classic way, # for instance, we can get the list of areas: res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "/input/areas/list", "depth": 1}, headers=headers, ) @@ -237,7 +237,7 @@ def test_get_study( # asserts that the GET /raw endpoint is able to read matrix containing NaN values res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": "output/20201014-1427eco/economy/mc-all/areas/de/id-monthly"}, headers=headers, ) @@ -247,7 +247,7 @@ def test_get_study( # Iterate over all possible combinations of path and depth for path, depth in itertools.product([None, "", "/"], [0, 1, 2]): res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": path, "depth": depth}, headers=headers, ) diff --git a/tests/integration/studies_blueprint/test_comments.py b/tests/integration/studies_blueprint/test_comments.py index 378be0aed5..39ce84e35b 100644 --- a/tests/integration/studies_blueprint/test_comments.py +++ b/tests/integration/studies_blueprint/test_comments.py @@ -20,7 +20,7 @@ def test_raw_study( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ This test verifies that we can retrieve and modify the comments of a study. @@ -29,7 +29,7 @@ def test_raw_study( # Get the comments of the study and compare with the expected file res = client.get( - f"/v1/studies/{study_id}/comments", + f"/v1/studies/{internal_study_id}/comments", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -41,7 +41,7 @@ def test_raw_study( # Ensure the duration is relatively short start = time.time() res = client.get( - f"/v1/studies/{study_id}/comments", + f"/v1/studies/{internal_study_id}/comments", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -50,7 +50,7 @@ def test_raw_study( # Update the comments of the study res = client.put( - f"/v1/studies/{study_id}/comments", + f"/v1/studies/{internal_study_id}/comments", headers={"Authorization": f"Bearer {user_access_token}"}, json={"comments": "Ceci est un commentaire en français."}, ) @@ -58,7 +58,7 @@ def test_raw_study( # Get the comments of the study and compare with the expected file res = client.get( - f"/v1/studies/{study_id}/comments", + f"/v1/studies/{internal_study_id}/comments", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -68,7 +68,7 @@ def test_variant_study( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ This test verifies that we can retrieve and modify the comments of a VARIANT study. @@ -76,7 +76,7 @@ def test_variant_study( """ # First, we create a copy of the study, and we convert it to a managed study. res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers={"Authorization": f"Bearer {user_access_token}"}, params={"dest": "default", "with_outputs": False, "use_task": False}, # type: ignore ) diff --git a/tests/integration/studies_blueprint/test_disk_usage.py b/tests/integration/studies_blueprint/test_disk_usage.py index 1685acad87..dcfb48a5b7 100644 --- a/tests/integration/studies_blueprint/test_disk_usage.py +++ b/tests/integration/studies_blueprint/test_disk_usage.py @@ -10,7 +10,7 @@ def test_disk_usage_endpoint( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, tmp_path: Path, ) -> None: """ @@ -23,7 +23,7 @@ def test_disk_usage_endpoint( user_headers = {"Authorization": f"Bearer {user_access_token}"} res = client.get( - f"/v1/studies/{study_id}/disk-usage", + f"/v1/studies/{internal_study_id}/disk-usage", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -32,7 +32,7 @@ def test_disk_usage_endpoint( # Copy the study in managed workspace in order to create a variant res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers=user_headers, params={"dest": "somewhere", "use_task": "false"}, ) diff --git a/tests/integration/studies_blueprint/test_study_matrix_index.py b/tests/integration/studies_blueprint/test_study_matrix_index.py index 4aeacceff4..7821ee6151 100644 --- a/tests/integration/studies_blueprint/test_study_matrix_index.py +++ b/tests/integration/studies_blueprint/test_study_matrix_index.py @@ -14,7 +14,7 @@ def test_get_study_matrix_index( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: user_access_token = {"Authorization": f"Bearer {user_access_token}"} @@ -23,7 +23,7 @@ def test_get_study_matrix_index( # Check the Common matrix index res = client.get( - f"/v1/studies/{study_id}/matrixindex", + f"/v1/studies/{internal_study_id}/matrixindex", headers=user_access_token, params={"path": "input/thermal/prepro/fr/01_solar/modulation"}, ) @@ -40,7 +40,7 @@ def test_get_study_matrix_index( # Check the TS Generator matrix index res = client.get( - f"/v1/studies/{study_id}/matrixindex", + f"/v1/studies/{internal_study_id}/matrixindex", headers=user_access_token, params={"path": "input/thermal/prepro/fr/01_solar/data"}, ) @@ -57,7 +57,7 @@ def test_get_study_matrix_index( # Check the time series res = client.get( - f"/v1/studies/{study_id}/matrixindex", + f"/v1/studies/{internal_study_id}/matrixindex", headers=user_access_token, params={"path": "input/thermal/series/fr/01_solar/series"}, ) @@ -75,7 +75,7 @@ def test_get_study_matrix_index( # Check the default matrix index # ============================== - res = client.get(f"/v1/studies/{study_id}/matrixindex", headers=user_access_token) + res = client.get(f"/v1/studies/{internal_study_id}/matrixindex", headers=user_access_token) assert res.status_code == 200 actual = res.json() expected = { @@ -90,7 +90,7 @@ def test_get_study_matrix_index( # ========================================================================= res = client.get( - f"/v1/studies/{study_id}/matrixindex", + f"/v1/studies/{internal_study_id}/matrixindex", headers=user_access_token, params={"path": "output/20201014-1427eco/economy/mc-all/areas/es/details-daily"}, ) diff --git a/tests/integration/studies_blueprint/test_synthesis.py b/tests/integration/studies_blueprint/test_synthesis.py index 1f10fa2989..2b5205824a 100644 --- a/tests/integration/studies_blueprint/test_synthesis.py +++ b/tests/integration/studies_blueprint/test_synthesis.py @@ -33,7 +33,7 @@ def test_raw_study( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ This test verifies that we can retrieve the synthesis of a study. @@ -42,7 +42,7 @@ def test_raw_study( # Get the synthesis of the study and compare with the expected file res = client.get( - f"/v1/studies/{study_id}/synthesis", + f"/v1/studies/{internal_study_id}/synthesis", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -53,7 +53,7 @@ def test_raw_study( # Ensure the duration is relatively short start = time.time() res = client.get( - f"/v1/studies/{study_id}/synthesis", + f"/v1/studies/{internal_study_id}/synthesis", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -64,7 +64,7 @@ def test_variant_study( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ This test verifies that we can retrieve and modify the synthesis of a VARIANT study. @@ -72,7 +72,7 @@ def test_variant_study( """ # First, we create a copy of the study, and we convert it to a managed study. res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers={"Authorization": f"Bearer {user_access_token}"}, params={"dest": "default", "with_outputs": False, "use_task": False}, # type: ignore ) diff --git a/tests/integration/studies_blueprint/test_update_tags.py b/tests/integration/studies_blueprint/test_update_tags.py index a65ece2f11..9ee37c7d70 100644 --- a/tests/integration/studies_blueprint/test_update_tags.py +++ b/tests/integration/studies_blueprint/test_update_tags.py @@ -10,7 +10,7 @@ def test_update_tags( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ This test verifies that we can update the tags of a study. @@ -20,7 +20,7 @@ def test_update_tags( # Classic usage: set some tags to a study study_tags = ["Tag1", "Tag2"] res = client.put( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"tags": study_tags}, ) @@ -33,7 +33,7 @@ def test_update_tags( # - "Tag2" is replaced by "Tag3". study_tags = ["tag1", "Tag3"] res = client.put( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"tags": study_tags}, ) @@ -46,7 +46,7 @@ def test_update_tags( # consecutive whitespaces are replaced by a single one. study_tags = [" \xa0Foo \t Bar \n ", " \t Baz\xa0\xa0"] res = client.put( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"tags": study_tags}, ) @@ -57,7 +57,7 @@ def test_update_tags( # We can have symbols in the tags study_tags = ["Foo-Bar", ":Baz%"] res = client.put( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"tags": study_tags}, ) @@ -69,12 +69,12 @@ def test_update_tags__invalid_tags( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: # We cannot have empty tags study_tags = [""] res = client.put( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"tags": study_tags}, ) @@ -86,7 +86,7 @@ def test_update_tags__invalid_tags( study_tags = ["very long tags, very long tags, very long tags"] assert len(study_tags[0]) > 40 res = client.put( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"tags": study_tags}, ) diff --git a/tests/integration/study_data_blueprint/test_advanced_parameters.py b/tests/integration/study_data_blueprint/test_advanced_parameters.py index b126349335..90eee2a88f 100644 --- a/tests/integration/study_data_blueprint/test_advanced_parameters.py +++ b/tests/integration/study_data_blueprint/test_advanced_parameters.py @@ -19,11 +19,11 @@ def test_get_advanced_parameters_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """Check `get_advanced_parameters_form_values` end point""" res = client.get( - f"/v1/studies/{study_id}/config/advancedparameters/form", + f"/v1/studies/{internal_study_id}/config/advancedparameters/form", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -55,12 +55,12 @@ def test_get_advanced_parameters_values( @pytest.mark.parametrize("study_version", [0, 880]) def test_set_advanced_parameters_values( - self, client: TestClient, user_access_token: str, study_id: str, study_version: int + self, client: TestClient, user_access_token: str, internal_study_id: str, study_version: int ): """Check `set_advanced_parameters_values` end point""" obj = {"initialReservoirLevels": "hot start"} res = client.put( - f"/v1/studies/{study_id}/config/advancedparameters/form", + f"/v1/studies/{internal_study_id}/config/advancedparameters/form", headers={"Authorization": f"Bearer {user_access_token}"}, json=obj, ) @@ -70,7 +70,7 @@ def test_set_advanced_parameters_values( if study_version: res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, params={"target_version": study_version}, ) @@ -82,7 +82,7 @@ def test_set_advanced_parameters_values( obj = {"unitCommitmentMode": "milp"} res = client.put( - f"/v1/studies/{study_id}/config/advancedparameters/form", + f"/v1/studies/{internal_study_id}/config/advancedparameters/form", headers={"Authorization": f"Bearer {user_access_token}"}, json=obj, ) diff --git a/tests/integration/study_data_blueprint/test_config_general.py b/tests/integration/study_data_blueprint/test_config_general.py index e64c50aa83..3084a86b4e 100644 --- a/tests/integration/study_data_blueprint/test_config_general.py +++ b/tests/integration/study_data_blueprint/test_config_general.py @@ -17,11 +17,11 @@ def test_get_general_form_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """Check `set_general_form_values` end point""" res = client.get( - f"/v1/studies/{study_id}/config/general/form", + f"/v1/studies/{internal_study_id}/config/general/form", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -49,12 +49,12 @@ def test_set_general_form_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """Check `set_general_form_values` end point""" obj = {"horizon": 2020} res = client.put( - f"/v1/studies/{study_id}/config/general/form", + f"/v1/studies/{internal_study_id}/config/general/form", headers={"Authorization": f"Bearer {user_access_token}"}, json=obj, ) diff --git a/tests/integration/study_data_blueprint/test_edit_matrix.py b/tests/integration/study_data_blueprint/test_edit_matrix.py index cb9e4702e9..28953d713b 100644 --- a/tests/integration/study_data_blueprint/test_edit_matrix.py +++ b/tests/integration/study_data_blueprint/test_edit_matrix.py @@ -241,7 +241,7 @@ def test_edit_matrix__thermal_cluster( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): # Given the following Area area_id = "fr" @@ -249,7 +249,7 @@ def test_edit_matrix__thermal_cluster( # Create a cluster cluster_id = "cluster 1" res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[ { @@ -273,7 +273,7 @@ def test_edit_matrix__thermal_cluster( } ] res = client.put( - f"/v1/studies/{study_id}/matrix?path=input/thermal/series/{area_id}/{cluster_id}/series", + f"/v1/studies/{internal_study_id}/matrix?path=input/thermal/series/{area_id}/{cluster_id}/series", headers={"Authorization": f"Bearer {user_access_token}"}, json=obj, ) @@ -281,7 +281,7 @@ def test_edit_matrix__thermal_cluster( # We can check the modified matrix res = client.get( - f"/v1/studies/{study_id}/raw?path=input/thermal/series/{area_id}/{cluster_id}/series", + f"/v1/studies/{internal_study_id}/raw?path=input/thermal/series/{area_id}/{cluster_id}/series", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() diff --git a/tests/integration/study_data_blueprint/test_hydro_allocation.py b/tests/integration/study_data_blueprint/test_hydro_allocation.py index d4b04dd332..47eb65f39d 100644 --- a/tests/integration/study_data_blueprint/test_hydro_allocation.py +++ b/tests/integration/study_data_blueprint/test_hydro_allocation.py @@ -20,12 +20,12 @@ def test_get_allocation_form_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """Check `get_allocation_form_values` end point""" area_id = "de" res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/allocation/form", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/allocation/form", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == http.HTTPStatus.OK, res.json() @@ -37,7 +37,7 @@ def test_get_allocation_form_values__variant( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ The purpose of this test is to check that we can get the form parameters from a study variant. @@ -46,7 +46,7 @@ def test_get_allocation_form_values__variant( """ # Create a managed study from the RAW study. res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers={"Authorization": f"Bearer {user_access_token}"}, params={"dest": "Clone", "with_outputs": False, "use_task": False}, ) @@ -109,13 +109,13 @@ def test_get_allocation_matrix( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, area_id: str, expected: t.List[t.List[float]], ) -> None: """Check `get_allocation_matrix` end point""" res = client.get( - f"/v1/studies/{study_id}/areas/hydro/allocation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/allocation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == http.HTTPStatus.OK, res.json() @@ -126,7 +126,7 @@ def test_set_allocation_form_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """Check `set_allocation_form_values` end point""" area_id = "de" @@ -137,7 +137,7 @@ def test_set_allocation_form_values( ] } res = client.put( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/allocation/form", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/allocation/form", headers={"Authorization": f"Bearer {user_access_token}"}, json=expected, ) @@ -147,7 +147,7 @@ def test_set_allocation_form_values( # check that the values are updated res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", headers={"Authorization": f"Bearer {user_access_token}"}, params={"path": "input/hydro/allocation", "depth": 3}, ) @@ -161,7 +161,7 @@ def test_set_allocation_form_values( } assert actual == expected - def test_create_area(self, client: TestClient, user_access_token: str, study_id: str) -> None: + def test_create_area(self, client: TestClient, user_access_token: str, internal_study_id: str) -> None: """ Given a study, when an area is created, the hydraulic allocation column for this area must be updated with the following values: @@ -171,14 +171,14 @@ def test_create_area(self, client: TestClient, user_access_token: str, study_id: """ area_info = AreaInfoDTO(id="north", name="NORTH", type=AreaType.AREA) res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", headers={"Authorization": f"Bearer {user_access_token}"}, data=area_info.json(), ) assert res.status_code == http.HTTPStatus.OK, res.json() res = client.get( - f"/v1/studies/{study_id}/areas/hydro/allocation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/allocation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == http.HTTPStatus.OK @@ -196,7 +196,7 @@ def test_create_area(self, client: TestClient, user_access_token: str, study_id: } assert actual == expected - def test_delete_area(self, client: TestClient, user_access_token: str, study_id: str) -> None: + def test_delete_area(self, client: TestClient, user_access_token: str, internal_study_id: str) -> None: """ Given a study, when an area is deleted, the hydraulic allocation column for this area must be removed. @@ -211,7 +211,7 @@ def test_delete_area(self, client: TestClient, user_access_token: str, study_id: } for prod_area, allocation_cfg in obj.items(): res = client.post( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", headers={"Authorization": f"Bearer {user_access_token}"}, params={"path": f"input/hydro/allocation/{prod_area}"}, json=allocation_cfg, @@ -221,7 +221,7 @@ def test_delete_area(self, client: TestClient, user_access_token: str, study_id: # Then we remove the "fr" zone. # The deletion should update the allocation matrix of all other zones. res = client.delete( - f"/v1/studies/{study_id}/areas/fr", + f"/v1/studies/{internal_study_id}/areas/fr", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == http.HTTPStatus.OK, res.json() @@ -229,7 +229,7 @@ def test_delete_area(self, client: TestClient, user_access_token: str, study_id: # Check that the "fr" column is removed from the hydraulic allocation matrix. # The row corresponding to "fr" must also be deleted. res = client.get( - f"/v1/studies/{study_id}/areas/hydro/allocation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/allocation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == http.HTTPStatus.OK, res.json() diff --git a/tests/integration/study_data_blueprint/test_hydro_correlation.py b/tests/integration/study_data_blueprint/test_hydro_correlation.py index 3aea6b60ae..c986ead8de 100644 --- a/tests/integration/study_data_blueprint/test_hydro_correlation.py +++ b/tests/integration/study_data_blueprint/test_hydro_correlation.py @@ -20,12 +20,12 @@ def test_get_correlation_form_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """Check `get_correlation_form_values` end point""" area_id = "fr" res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/correlation/form", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/correlation/form", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -44,7 +44,7 @@ def test_set_correlation_form_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """Check `set_correlation_form_values` end point""" area_id = "fr" @@ -57,7 +57,7 @@ def test_set_correlation_form_values( ] } res = client.put( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/correlation/form", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/correlation/form", headers={"Authorization": f"Bearer {user_access_token}"}, json=obj, ) @@ -74,7 +74,7 @@ def test_set_correlation_form_values( # check that the form is updated correctly res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/correlation/form", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/correlation/form", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -90,7 +90,7 @@ def test_set_correlation_form_values( # check that the matrix is symmetric res = client.get( - f"/v1/studies/{study_id}/areas/hydro/correlation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/correlation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -158,14 +158,14 @@ def test_get_correlation_matrix( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, columns: str, expected: List[List[float]], ): """Check `get_correlation_matrix` end point""" query = f"columns={columns}" if columns else "" res = client.get( - f"/v1/studies/{study_id}/areas/hydro/correlation/matrix?{query}", + f"/v1/studies/{internal_study_id}/areas/hydro/correlation/matrix?{query}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -176,7 +176,7 @@ def test_set_correlation_matrix( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): """Check `set_correlation_matrix` end point""" obj = { @@ -190,7 +190,7 @@ def test_set_correlation_matrix( "index": ["de", "es", "fr", "it"], } res = client.put( - f"/v1/studies/{study_id}/areas/hydro/correlation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/correlation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, json=obj, ) @@ -200,7 +200,7 @@ def test_set_correlation_matrix( assert actual == expected res = client.get( - f"/v1/studies/{study_id}/areas/hydro/correlation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/correlation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -217,7 +217,7 @@ def test_set_correlation_matrix( } assert actual == expected - def test_create_area(self, client: TestClient, user_access_token: str, study_id: str): + def test_create_area(self, client: TestClient, user_access_token: str, internal_study_id: str): """ Given a study, when an area is created, the hydraulic correlation column for this area must be updated with the following values: @@ -227,14 +227,14 @@ def test_create_area(self, client: TestClient, user_access_token: str, study_id: """ area_info = AreaInfoDTO(id="north", name="NORTH", type="AREA") res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", headers={"Authorization": f"Bearer {user_access_token}"}, data=area_info.json(), ) assert res.status_code == HTTPStatus.OK, res.json() res = client.get( - f"/v1/studies/{study_id}/areas/hydro/correlation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/correlation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK @@ -252,7 +252,7 @@ def test_create_area(self, client: TestClient, user_access_token: str, study_id: } assert actual == expected - def test_delete_area(self, client: TestClient, user_access_token: str, study_id: str): + def test_delete_area(self, client: TestClient, user_access_token: str, internal_study_id: str): """ Given a study, when an area is deleted, the hydraulic correlation column for this area must be removed. @@ -270,7 +270,7 @@ def test_delete_area(self, client: TestClient, user_access_token: str, study_id: } } res = client.post( - f"/v1/studies/{study_id}/raw?path=input/hydro/prepro/correlation", + f"/v1/studies/{internal_study_id}/raw?path=input/hydro/prepro/correlation", headers={"Authorization": f"Bearer {user_access_token}"}, json=correlation_cfg, ) @@ -279,7 +279,7 @@ def test_delete_area(self, client: TestClient, user_access_token: str, study_id: # Then we remove the "fr" zone. # The deletion should update the correlation matrix of all other zones. res = client.delete( - f"/v1/studies/{study_id}/areas/fr", + f"/v1/studies/{internal_study_id}/areas/fr", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -287,7 +287,7 @@ def test_delete_area(self, client: TestClient, user_access_token: str, study_id: # Check that the "fr" column is removed from the hydraulic correlation matrix. # The row corresponding to "fr" must also be deleted. res = client.get( - f"/v1/studies/{study_id}/areas/hydro/correlation/matrix", + f"/v1/studies/{internal_study_id}/areas/hydro/correlation/matrix", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == HTTPStatus.OK, res.json() diff --git a/tests/integration/study_data_blueprint/test_hydro_inflow_structure.py b/tests/integration/study_data_blueprint/test_hydro_inflow_structure.py index 0a8bb82ed6..f673882752 100644 --- a/tests/integration/study_data_blueprint/test_hydro_inflow_structure.py +++ b/tests/integration/study_data_blueprint/test_hydro_inflow_structure.py @@ -18,7 +18,7 @@ def test_get_inflow_structure( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): user_header = {"Authorization": f"Bearer {user_access_token}"} area_id = "fr" @@ -29,7 +29,7 @@ def test_get_inflow_structure( # Check that the default values are returned res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/inflow-structure", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/inflow-structure", headers=user_header, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -40,7 +40,7 @@ def test_get_inflow_structure( # Update the values obj = {"interMonthlyCorrelation": 0.8} res = client.put( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/inflow-structure", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/inflow-structure", headers=user_header, json=obj, ) @@ -48,7 +48,7 @@ def test_get_inflow_structure( # Check that the right values are returned res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/inflow-structure", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/inflow-structure", headers=user_header, ) assert res.status_code == HTTPStatus.OK, res.json() @@ -62,7 +62,7 @@ def test_get_inflow_structure( # Create a managed study from the RAW study. res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers={"Authorization": f"Bearer {user_access_token}"}, params={"dest": "Clone", "with_outputs": False, "use_task": False}, ) @@ -132,7 +132,7 @@ def test_update_inflow_structure__invalid_values( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): user_header = {"Authorization": f"Bearer {user_access_token}"} area_id = "fr" @@ -140,7 +140,7 @@ def test_update_inflow_structure__invalid_values( # Update the values with invalid values obj = {"interMonthlyCorrelation": 1.1} res = client.put( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/inflow-structure", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/inflow-structure", headers=user_header, json=obj, ) @@ -148,7 +148,7 @@ def test_update_inflow_structure__invalid_values( obj = {"interMonthlyCorrelation": -0.1} res = client.put( - f"/v1/studies/{study_id}/areas/{area_id}/hydro/inflow-structure", + f"/v1/studies/{internal_study_id}/areas/{area_id}/hydro/inflow-structure", headers=user_header, json=obj, ) diff --git a/tests/integration/study_data_blueprint/test_renewable.py b/tests/integration/study_data_blueprint/test_renewable.py index 8a9d575d97..b6c450e8f3 100644 --- a/tests/integration/study_data_blueprint/test_renewable.py +++ b/tests/integration/study_data_blueprint/test_renewable.py @@ -51,11 +51,11 @@ def test_lifecycle( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: # Upgrade study to version 810 res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, params={"target_version": 810}, ) @@ -75,7 +75,7 @@ def test_lifecycle( "data": {"renewable-generation-modelling": "clusters"}, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "update_config", "args": args}], ) @@ -95,7 +95,7 @@ def test_lifecycle( attempts = [{}, {"name": ""}, {"name": "!??"}] for attempt in attempts: res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json=attempt, ) @@ -112,7 +112,7 @@ def test_lifecycle( "tsInterpretation": "production-factor", } res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json=fr_solar_pv_props, ) @@ -125,7 +125,7 @@ def test_lifecycle( # reading the properties of a renewable cluster res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -139,14 +139,14 @@ def test_lifecycle( matrix_path = f"input/renewables/series/{area_id}/{fr_solar_pv_id.lower()}/series" args = {"target": matrix_path, "matrix": matrix} res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", json=[{"action": "replace_matrix", "args": args}], headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code in {200, 201}, res.json() res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": matrix_path}, headers={"Authorization": f"Bearer {user_access_token}"}, ) @@ -159,7 +159,7 @@ def test_lifecycle( # Reading the list of renewable clusters res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -167,7 +167,7 @@ def test_lifecycle( # updating properties res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "name": "FR Solar pv old 1", @@ -183,7 +183,7 @@ def test_lifecycle( assert res.json() == fr_solar_pv_cfg res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -195,7 +195,7 @@ def test_lifecycle( # updating properties res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "nominalCapacity": 2260, @@ -215,7 +215,7 @@ def test_lifecycle( # The `unitCount` property must be an integer greater than 0. bad_properties = {"unitCount": 0} res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json=bad_properties, ) @@ -224,7 +224,7 @@ def test_lifecycle( # The renewable cluster properties should not have been updated. res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -236,7 +236,7 @@ def test_lifecycle( new_name = "Duplicate of SolarPV" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/renewables/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/renewables/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": new_name}, ) @@ -251,7 +251,7 @@ def test_lifecycle( # asserts the matrix has also been duplicated new_cluster_matrix_path = f"input/renewables/series/{area_id}/{duplicated_id.lower()}/series" res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": new_cluster_matrix_path}, headers={"Authorization": f"Bearer {user_access_token}"}, ) @@ -265,7 +265,7 @@ def test_lifecycle( # To delete a renewable cluster, we need to provide its ID. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json=[fr_solar_pv_id], ) @@ -275,7 +275,7 @@ def test_lifecycle( # If the renewable cluster list is empty, the deletion should be a no-op. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json=[], ) @@ -286,7 +286,7 @@ def test_lifecycle( # Create two clusters other_cluster_name = "Other Cluster 1" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json={"name": other_cluster_name}, ) @@ -294,7 +294,7 @@ def test_lifecycle( other_cluster_id1 = res.json()["id"] res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json={"name": "Other Cluster 2"}, ) @@ -304,7 +304,7 @@ def test_lifecycle( # We can delete two renewable clusters at once. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json=[other_cluster_id2, duplicated_id], ) @@ -313,7 +313,7 @@ def test_lifecycle( # There should only be one remaining cluster res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200 @@ -328,7 +328,7 @@ def test_lifecycle( bad_area_id = "bad_area" res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json=[fr_solar_pv_id], ) @@ -357,7 +357,7 @@ def test_lifecycle( # Check GET with wrong `area_id` res = client.get( - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) obj = res.json() @@ -388,7 +388,7 @@ def test_lifecycle( # Check POST with wrong `area_id` res = client.post( - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "name": fr_solar_pv, @@ -407,7 +407,7 @@ def test_lifecycle( # Check POST with wrong `group` res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", headers={"Authorization": f"Bearer {user_access_token}"}, json={"name": fr_solar_pv, "group": "GroupFoo"}, ) @@ -418,7 +418,7 @@ def test_lifecycle( # Check PATCH with the wrong `area_id` res = client.patch( - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/renewable/{fr_solar_pv_id}", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/renewable/{fr_solar_pv_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "group": "Wind Onshore", @@ -436,7 +436,7 @@ def test_lifecycle( # Check PATCH with the wrong `cluster_id` bad_cluster_id = "bad_cluster" res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable/{bad_cluster_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable/{bad_cluster_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "group": "Wind Onshore", @@ -470,7 +470,7 @@ def test_lifecycle( # Cannot duplicate a fake cluster unknown_id = "unknown" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/renewables/{unknown_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/renewables/{unknown_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": "duplicata"}, ) @@ -481,7 +481,7 @@ def test_lifecycle( # Cannot duplicate with an existing id res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/renewables/{other_cluster_id1}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/renewables/{other_cluster_id1}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": other_cluster_name.upper()}, # different case, but same ID ) diff --git a/tests/integration/study_data_blueprint/test_st_storage.py b/tests/integration/study_data_blueprint/test_st_storage.py index b8aa0de878..68fe46b138 100644 --- a/tests/integration/study_data_blueprint/test_st_storage.py +++ b/tests/integration/study_data_blueprint/test_st_storage.py @@ -49,7 +49,7 @@ def test_lifecycle__nominal( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, study_type: str, study_version: int, default_output: t.Dict[str, t.Any], @@ -85,7 +85,7 @@ def test_lifecycle__nominal( # Upgrade study to version 860 or above res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers=user_headers, params={"target_version": study_version}, ) @@ -96,22 +96,22 @@ def test_lifecycle__nominal( # Copies the study, to convert it into a managed one. res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers={"Authorization": f"Bearer {user_access_token}"}, params={"dest": "default", "with_outputs": False, "use_task": False}, # type: ignore ) assert res.status_code == 201, res.json() - study_id = res.json() + internal_study_id = res.json() if study_type == "variant": # Create Variant res = client.post( - f"/v1/studies/{study_id}/variants", + f"/v1/studies/{internal_study_id}/variants", headers=user_headers, params={"name": "Variant 1"}, ) assert res.status_code in {200, 201}, res.json() - study_id = res.json() + internal_study_id = res.json() # ============================= # SHORT-TERM STORAGE CREATION @@ -126,7 +126,7 @@ def test_lifecycle__nominal( attempts = [{}, {"name": ""}, {"name": "!??"}] for attempt in attempts: res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=attempt, ) @@ -143,7 +143,7 @@ def test_lifecycle__nominal( "reservoirCapacity": 1500, } res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=siemens_properties, ) @@ -155,7 +155,7 @@ def test_lifecycle__nominal( # reading the properties of a short-term storage res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -169,7 +169,7 @@ def test_lifecycle__nominal( array = np.random.randint(0, 1000, size=(8760, 1)) array_list = array.tolist() res = client.put( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}/series/inflows", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}/series/inflows", headers=user_headers, json={ "index": list(range(array.shape[0])), @@ -182,7 +182,7 @@ def test_lifecycle__nominal( # reading the matrix of a short-term storage res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}/series/inflows", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}/series/inflows", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -192,7 +192,7 @@ def test_lifecycle__nominal( # validating the matrices of a short-term storage res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}/validate", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}/validate", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -204,7 +204,7 @@ def test_lifecycle__nominal( # Reading the list of short-term storages res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -212,7 +212,7 @@ def test_lifecycle__nominal( # updating properties res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers=user_headers, json={ "name": "New Siemens Battery", @@ -228,7 +228,7 @@ def test_lifecycle__nominal( assert res.json() == siemens_output res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -240,7 +240,7 @@ def test_lifecycle__nominal( # updating properties res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers=user_headers, json={ "initialLevel": 0.59, @@ -260,7 +260,7 @@ def test_lifecycle__nominal( # The `efficiency` property must be a float between 0 and 1. bad_properties = {"efficiency": 2.0} res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers=user_headers, json=bad_properties, ) @@ -269,7 +269,7 @@ def test_lifecycle__nominal( # The short-term storage properties should not have been updated. res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -281,7 +281,7 @@ def test_lifecycle__nominal( new_name = "Duplicate of Siemens" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": new_name}, ) @@ -295,7 +295,7 @@ def test_lifecycle__nominal( # asserts the matrix has also been duplicated res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{duplicated_id}/series/inflows", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{duplicated_id}/series/inflows", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200 @@ -308,7 +308,7 @@ def test_lifecycle__nominal( # To delete a short-term storage, we need to provide its ID. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=[siemens_battery_id], ) @@ -318,7 +318,7 @@ def test_lifecycle__nominal( # If the short-term storage list is empty, the deletion should be a no-op. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=[], ) @@ -338,7 +338,7 @@ def test_lifecycle__nominal( "initialLevelOptim": False, } res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=siemens_properties, ) @@ -357,7 +357,7 @@ def test_lifecycle__nominal( "initialLevel": 1, } res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=grand_maison_properties, ) @@ -367,7 +367,7 @@ def test_lifecycle__nominal( # We can check that we have 2 short-term storages in the list. # Reading the list of short-term storages res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -378,7 +378,7 @@ def test_lifecycle__nominal( # We can delete the three short-term storages at once. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=[grand_maison_id, duplicated_output["id"]], ) @@ -387,7 +387,7 @@ def test_lifecycle__nominal( # Only one st-storage should remain. res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, ) assert res.status_code == 200, res.json() @@ -401,7 +401,7 @@ def test_lifecycle__nominal( bad_area_id = "bad_area" res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{bad_area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/storages", headers=user_headers, json=[siemens_battery_id], ) @@ -426,7 +426,7 @@ def test_lifecycle__nominal( # Check get with wrong `area_id` res = client.get( - f"/v1/studies/{study_id}/areas/{bad_area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/storages/{siemens_battery_id}", headers=user_headers, ) obj = res.json() @@ -457,7 +457,7 @@ def test_lifecycle__nominal( # Check POST with wrong `area_id` res = client.post( - f"/v1/studies/{study_id}/areas/{bad_area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/storages", headers=user_headers, json={"name": siemens_battery, "group": "Battery"}, ) @@ -468,7 +468,7 @@ def test_lifecycle__nominal( # Check POST with wrong `group` res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json={"name": siemens_battery, "group": "GroupFoo"}, ) @@ -479,7 +479,7 @@ def test_lifecycle__nominal( # Check PATCH with the wrong `area_id` res = client.patch( - f"/v1/studies/{study_id}/areas/{bad_area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/storages/{siemens_battery_id}", headers=user_headers, json={"efficiency": 1.0}, ) @@ -491,7 +491,7 @@ def test_lifecycle__nominal( # Check PATCH with the wrong `storage_id` bad_storage_id = "bad_storage" res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{bad_storage_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{bad_storage_id}", headers=user_headers, json={"efficiency": 1.0}, ) @@ -516,7 +516,7 @@ def test_lifecycle__nominal( # Cannot duplicate a unknown st-storage unknown_id = "unknown" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{unknown_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{unknown_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": "duplicata"}, ) @@ -527,7 +527,7 @@ def test_lifecycle__nominal( # Cannot duplicate with an existing id res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages/{siemens_battery_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages/{siemens_battery_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": siemens_battery.upper()}, # different case, but same ID ) @@ -540,7 +540,7 @@ def test_lifecycle__nominal( # Cannot specify the field 'enabled' before v8.8 properties = {"enabled": False, "name": "fake_name", "group": "Battery"} res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", headers=user_headers, json=properties, ) diff --git a/tests/integration/study_data_blueprint/test_table_mode.py b/tests/integration/study_data_blueprint/test_table_mode.py index 3ffbeb2b46..2e36b55490 100644 --- a/tests/integration/study_data_blueprint/test_table_mode.py +++ b/tests/integration/study_data_blueprint/test_table_mode.py @@ -23,7 +23,7 @@ class TestTableMode: @pytest.mark.parametrize("study_version", [0, 810, 830, 860, 870, 880]) def test_lifecycle__nominal( - self, client: TestClient, user_access_token: str, study_id: str, study_version: int + self, client: TestClient, user_access_token: str, internal_study_id: str, study_version: int ) -> None: client.headers = {"Authorization": f"Bearer {user_access_token}"} @@ -35,7 +35,7 @@ def test_lifecycle__nominal( # Upgrade the study to the desired version if study_version: res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", params={"target_version": study_version}, ) assert res.status_code == 200, res.json() @@ -45,7 +45,7 @@ def test_lifecycle__nominal( assert task.status == TaskStatus.COMPLETED, task # Create another link to test specific bug. - res = client.post(f"/v1/studies/{study_id}/links", json={"area1": "de", "area2": "it"}) + res = client.post(f"/v1/studies/{internal_study_id}/links", json={"area1": "de", "area2": "it"}) assert res.status_code in [200, 201], res.json() # Table Mode - Area @@ -83,7 +83,7 @@ def test_lifecycle__nominal( _es_values["adequacyPatchMode"] = "inside" res = client.put( - f"/v1/studies/{study_id}/table-mode/areas", + f"/v1/studies/{internal_study_id}/table-mode/areas", json={ "de": _de_values, "es": _es_values, @@ -147,7 +147,7 @@ def test_lifecycle__nominal( actual = res.json() assert actual == expected_areas - res = client.get(f"/v1/studies/{study_id}/table-mode/areas") + res = client.get(f"/v1/studies/{internal_study_id}/table-mode/areas") assert res.status_code == 200, res.json() actual = res.json() assert actual == expected_areas @@ -158,7 +158,7 @@ def test_lifecycle__nominal( "averageUnsuppliedEnergyCost": 456, } res = client.put( - f"/v1/studies/{study_id}/table-mode/areas", + f"/v1/studies/{internal_study_id}/table-mode/areas", json={"de": _de_values}, ) assert res.status_code == 200, res.json() @@ -191,7 +191,7 @@ def test_lifecycle__nominal( } res = client.put( - f"/v1/studies/{study_id}/table-mode/links", + f"/v1/studies/{internal_study_id}/table-mode/links", json={ "de / fr": { "colorRgb": "#FFA500", @@ -287,7 +287,7 @@ def test_lifecycle__nominal( del expected_result["de / it"] assert actual == expected_result - res = client.get(f"/v1/studies/{study_id}/table-mode/links") + res = client.get(f"/v1/studies/{internal_study_id}/table-mode/links") assert res.status_code == 200, res.json() actual = res.json() # asserts the `de / it` link is not removed. @@ -354,7 +354,7 @@ def test_lifecycle__nominal( _solar_values.update({"costGeneration": "useCostTimeseries", "efficiency": 87, "variableOMCost": -12.5}) res = client.put( - f"/v1/studies/{study_id}/table-mode/thermals", + f"/v1/studies/{internal_study_id}/table-mode/thermals", json={ "de / 01_solar": _solar_values, "de / 02_wind_on": _wind_on_values, @@ -437,7 +437,7 @@ def test_lifecycle__nominal( assert res.json()["de / 02_wind_on"] == expected_thermals["de / 02_wind_on"] res = client.get( - f"/v1/studies/{study_id}/table-mode/thermals", + f"/v1/studies/{internal_study_id}/table-mode/thermals", params={"columns": ",".join(["group", "unitCount", "nominalCapacity", "so2"])}, ) assert res.status_code == 200, res.json() @@ -500,7 +500,7 @@ def test_lifecycle__nominal( "data": {"renewable-generation-modelling": "clusters"}, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", json=[{"action": "update_config", "args": args}], ) assert res.status_code == 200, res.json() @@ -559,7 +559,7 @@ def test_lifecycle__nominal( for area_id, generators in generators_by_country.items(): for generator_id, generator in generators.items(): res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/renewable", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/renewable", json=generator, ) res.raise_for_status() @@ -584,7 +584,7 @@ def test_lifecycle__nominal( # Update some generators using the table mode res = client.put( - f"/v1/studies/{study_id}/table-mode/renewables", + f"/v1/studies/{internal_study_id}/table-mode/renewables", json={ "fr / Dieppe": {"enabled": False}, "fr / La Rochelle": {"enabled": True, "nominalCapacity": 3.1, "unitCount": 2}, @@ -594,7 +594,7 @@ def test_lifecycle__nominal( assert res.status_code == 200, res.json() res = client.get( - f"/v1/studies/{study_id}/table-mode/renewables", + f"/v1/studies/{internal_study_id}/table-mode/renewables", params={"columns": ",".join(["group", "enabled", "unitCount", "nominalCapacity"])}, ) assert res.status_code == 200, res.json() @@ -679,7 +679,7 @@ def test_lifecycle__nominal( for area_id, storages in storage_by_country.items(): for storage_id, storage in storages.items(): res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/storages", + f"/v1/studies/{internal_study_id}/areas/{area_id}/storages", json=storage, ) res.raise_for_status() @@ -692,7 +692,7 @@ def test_lifecycle__nominal( _it_storage3_values["enabled"] = False res = client.put( - f"/v1/studies/{study_id}/table-mode/st-storages", + f"/v1/studies/{internal_study_id}/table-mode/st-storages", json={ "fr / siemens": _fr_siemes_values, "fr / tesla": _fr_tesla_values, @@ -760,7 +760,7 @@ def test_lifecycle__nominal( assert actual == expected res = client.get( - f"/v1/studies/{study_id}/table-mode/st-storages", + f"/v1/studies/{internal_study_id}/table-mode/st-storages", params={ "columns": ",".join( [ @@ -810,7 +810,7 @@ def test_lifecycle__nominal( # Create a cluster in fr fr_id = "fr" res = client.post( - f"/v1/studies/{study_id}/areas/{fr_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{fr_id}/clusters/thermal", json={ "name": "Cluster 1", "group": "Nuclear", @@ -822,7 +822,7 @@ def test_lifecycle__nominal( # Create Binding Constraints res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", + f"/v1/studies/{internal_study_id}/bindingconstraints", json={ "name": "Binding Constraint 1", "enabled": True, @@ -833,7 +833,7 @@ def test_lifecycle__nominal( assert res.status_code == 200, res.json() res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", + f"/v1/studies/{internal_study_id}/bindingconstraints", json={ "name": "Binding Constraint 2", "enabled": False, @@ -874,7 +874,7 @@ def test_lifecycle__nominal( _bc2_values["group"] = "My BC Group" res = client.put( - f"/v1/studies/{study_id}/table-mode/binding-constraints", + f"/v1/studies/{internal_study_id}/table-mode/binding-constraints", json={ "binding constraint 1": _bc1_values, "binding constraint 2": _bc2_values, @@ -909,7 +909,7 @@ def test_lifecycle__nominal( assert actual == expected_binding res = client.get( - f"/v1/studies/{study_id}/table-mode/binding-constraints", + f"/v1/studies/{internal_study_id}/table-mode/binding-constraints", params={"columns": ""}, ) assert res.status_code == 200, res.json() diff --git a/tests/integration/study_data_blueprint/test_thermal.py b/tests/integration/study_data_blueprint/test_thermal.py index c294d0c235..33e9aef03d 100644 --- a/tests/integration/study_data_blueprint/test_thermal.py +++ b/tests/integration/study_data_blueprint/test_thermal.py @@ -287,7 +287,7 @@ class TestThermal: "version", [pytest.param(0, id="No Upgrade"), pytest.param(860, id="v8.6"), pytest.param(870, id="v8.7")] ) def test_lifecycle( - self, client: TestClient, user_access_token: str, study_id: str, admin_access_token: str, version: int + self, client: TestClient, user_access_token: str, internal_study_id: str, admin_access_token: str, version: int ) -> None: # ============================= # STUDY UPGRADE @@ -295,7 +295,7 @@ def test_lifecycle( if version != 0: res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {admin_access_token}"}, params={"target_version": version}, ) @@ -337,7 +337,7 @@ def test_lifecycle( attempts = [{}, {"name": ""}, {"name": "!??"}] for attempt in attempts: res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=attempt, ) @@ -360,7 +360,7 @@ def test_lifecycle( "marketBidCost": 181.267, } res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=fr_gas_conventional_props, ) @@ -385,7 +385,7 @@ def test_lifecycle( # reading the properties of a thermal cluster res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -399,14 +399,14 @@ def test_lifecycle( matrix_path = f"input/thermal/prepro/{area_id}/{fr_gas_conventional_id.lower()}/data" args = {"target": matrix_path, "matrix": matrix} res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", json=[{"action": "replace_matrix", "args": args}], headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code in {200, 201}, res.json() res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": matrix_path}, headers={"Authorization": f"Bearer {user_access_token}"}, ) @@ -419,7 +419,7 @@ def test_lifecycle( # Reading the list of thermal clusters res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -427,7 +427,7 @@ def test_lifecycle( # updating properties res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "name": "FR_Gas conventional old 1", @@ -443,7 +443,7 @@ def test_lifecycle( assert res.json() == fr_gas_conventional_cfg res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -455,7 +455,7 @@ def test_lifecycle( # updating properties res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "marginalCost": 182.456, @@ -477,7 +477,7 @@ def test_lifecycle( # The `unitCount` property must be an integer greater than 0. bad_properties = {"unitCount": 0} res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json=bad_properties, ) @@ -486,7 +486,7 @@ def test_lifecycle( # The thermal cluster properties should not have been updated. res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -494,7 +494,7 @@ def test_lifecycle( # Update with a pollutant. Should succeed even with versions prior to v8.6 res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"nox": 10.0}, ) @@ -503,7 +503,7 @@ def test_lifecycle( # Update with the field `efficiency`. Should succeed even with versions prior to v8.7 res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={"efficiency": 97.0}, ) @@ -516,7 +516,7 @@ def test_lifecycle( new_name = "Duplicate of Fr_Gas_Conventional" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/thermals/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/thermals/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": new_name}, ) @@ -536,7 +536,7 @@ def test_lifecycle( # asserts the matrix has also been duplicated new_cluster_matrix_path = f"input/thermal/prepro/{area_id}/{duplicated_id.lower()}/data" res = client.get( - f"/v1/studies/{study_id}/raw", + f"/v1/studies/{internal_study_id}/raw", params={"path": new_cluster_matrix_path}, headers={"Authorization": f"Bearer {user_access_token}"}, ) @@ -549,7 +549,7 @@ def test_lifecycle( # Everything is fine at the beginning res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200 @@ -559,14 +559,14 @@ def test_lifecycle( _upload_matrix( client, user_access_token, - study_id, + internal_study_id, f"input/thermal/series/{area_id}/{fr_gas_conventional_id.lower()}/series", pd.DataFrame(np.random.randint(0, 10, size=(4, 1))), ) # Validation should fail res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 422 @@ -578,14 +578,14 @@ def test_lifecycle( _upload_matrix( client, user_access_token, - study_id, + internal_study_id, f"input/thermal/series/{area_id}/{fr_gas_conventional_id.lower()}/series", pd.DataFrame(np.random.randint(0, 10, size=(8760, 4))), ) # Validation should succeed again res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200 @@ -596,14 +596,14 @@ def test_lifecycle( _upload_matrix( client, user_access_token, - study_id, + internal_study_id, f"input/thermal/series/{area_id}/{fr_gas_conventional_id.lower()}/CO2Cost", pd.DataFrame(np.random.randint(0, 10, size=(8760, 3))), ) # Validation should fail res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{fr_gas_conventional_id}/validate", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 422 @@ -640,7 +640,7 @@ def test_lifecycle( # noinspection SpellCheckingInspection res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", + f"/v1/studies/{internal_study_id}/bindingconstraints", json=bc_obj, headers={"Authorization": f"Bearer {user_access_token}"}, ) @@ -649,7 +649,7 @@ def test_lifecycle( # verify that we can't delete the thermal cluster because it is referenced in a binding constraint res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=[fr_gas_conventional_id], ) @@ -660,7 +660,7 @@ def test_lifecycle( # delete the binding constraint res = client.delete( - f"/v1/studies/{study_id}/bindingconstraints/{bc_obj['name']}", + f"/v1/studies/{internal_study_id}/bindingconstraints/{bc_obj['name']}", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -668,7 +668,7 @@ def test_lifecycle( # Now we can delete the thermal cluster res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=[fr_gas_conventional_id], ) @@ -677,7 +677,7 @@ def test_lifecycle( # check that the binding constraint has been deleted # noinspection SpellCheckingInspection res = client.get( - f"/v1/studies/{study_id}/bindingconstraints", + f"/v1/studies/{internal_study_id}/bindingconstraints", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -686,7 +686,7 @@ def test_lifecycle( # If the thermal cluster list is empty, the deletion should be a no-op. res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=[], ) @@ -699,7 +699,7 @@ def test_lifecycle( other_cluster_id2 = "02_wind_on" res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=[other_cluster_id1, other_cluster_id2], ) @@ -708,7 +708,7 @@ def test_lifecycle( # The list of thermal clusters should not contain the deleted ones. res = client.get( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200, res.json() @@ -724,7 +724,7 @@ def test_lifecycle( bad_area_id = "bad_area" res = client.request( "DELETE", - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json=[fr_gas_conventional_id], ) @@ -753,7 +753,7 @@ def test_lifecycle( # Check GET with wrong `area_id` res = client.get( - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) obj = res.json() @@ -784,7 +784,7 @@ def test_lifecycle( # Check POST with wrong `area_id` res = client.post( - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "name": fr_gas_conventional, @@ -807,7 +807,7 @@ def test_lifecycle( # Check POST with wrong `group` res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal", headers={"Authorization": f"Bearer {user_access_token}"}, json={"name": fr_gas_conventional, "group": "GroupFoo"}, ) @@ -818,7 +818,7 @@ def test_lifecycle( # Check PATCH with the wrong `area_id` res = client.patch( - f"/v1/studies/{study_id}/areas/{bad_area_id}/clusters/thermal/{fr_gas_conventional_id}", + f"/v1/studies/{internal_study_id}/areas/{bad_area_id}/clusters/thermal/{fr_gas_conventional_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "group": "Oil", @@ -840,7 +840,7 @@ def test_lifecycle( # Check PATCH with the wrong `cluster_id` bad_cluster_id = "bad_cluster" res = client.patch( - f"/v1/studies/{study_id}/areas/{area_id}/clusters/thermal/{bad_cluster_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/clusters/thermal/{bad_cluster_id}", headers={"Authorization": f"Bearer {user_access_token}"}, json={ "group": "Oil", @@ -882,7 +882,7 @@ def test_lifecycle( # Cannot duplicate a fake cluster unknown_id = "unknown" res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/thermals/{unknown_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/thermals/{unknown_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": "duplicate"}, ) @@ -893,7 +893,7 @@ def test_lifecycle( # Cannot duplicate with an existing id res = client.post( - f"/v1/studies/{study_id}/areas/{area_id}/thermals/{duplicated_id}", + f"/v1/studies/{internal_study_id}/areas/{area_id}/thermals/{duplicated_id}", headers={"Authorization": f"Bearer {user_access_token}"}, params={"newName": new_name.upper()}, # different case but same ID ) @@ -1048,7 +1048,7 @@ def test_variant_lifecycle(self, client: TestClient, user_access_token: str, var "remove_cluster", ] - def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: str, study_id: str) -> None: + def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: str, internal_study_id: str) -> None: """ Test that creating a thermal cluster with invalid properties raises a validation error. """ @@ -1057,7 +1057,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s # Create an area "area_1" in the study res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={ "name": "area_1", "type": "AREA", @@ -1068,7 +1068,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s # Create an area "area_2" in the study res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={ "name": "area_2", "type": "AREA", @@ -1079,7 +1079,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s # Create an area "area_3" in the study res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={ "name": "area_3", "type": "AREA", @@ -1090,7 +1090,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s # Create a thermal cluster in the study for area_1 res = client.post( - f"/v1/studies/{study_id}/areas/area_1/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_1/clusters/thermal", json={ "name": "cluster_1", "group": "Nuclear", @@ -1103,7 +1103,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s # Create a thermal cluster in the study for area_2 res = client.post( - f"/v1/studies/{study_id}/areas/area_2/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_2/clusters/thermal", json={ "name": "cluster_2", "group": "Nuclear", @@ -1116,7 +1116,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s # Create a thermal cluster in the study for area_3 res = client.post( - f"/v1/studies/{study_id}/areas/area_3/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_3/clusters/thermal", json={ "name": "cluster_3", "group": "Nuclear", @@ -1143,7 +1143,7 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s ], } res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", + f"/v1/studies/{internal_study_id}/bindingconstraints", json=bc_obj, ) assert res.status_code == 200, res.json() @@ -1164,54 +1164,54 @@ def test_thermal_cluster_deletion(self, client: TestClient, user_access_token: s ], } res = client.post( - f"/v1/studies/{study_id}/bindingconstraints", + f"/v1/studies/{internal_study_id}/bindingconstraints", json=bc_obj, ) assert res.status_code == 200, res.json() # check that deleting the thermal cluster in area_1 fails res = client.delete( - f"/v1/studies/{study_id}/areas/area_1/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_1/clusters/thermal", json=["cluster_1"], ) assert res.status_code == 403, res.json() # now delete the binding constraint that references the thermal cluster in area_1 res = client.delete( - f"/v1/studies/{study_id}/bindingconstraints/bc_1", + f"/v1/studies/{internal_study_id}/bindingconstraints/bc_1", ) assert res.status_code == 200, res.json() # check that deleting the thermal cluster in area_1 succeeds res = client.delete( - f"/v1/studies/{study_id}/areas/area_1/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_1/clusters/thermal", json=["cluster_1"], ) assert res.status_code == 204, res.json() # check that deleting the thermal cluster in area_2 fails res = client.delete( - f"/v1/studies/{study_id}/areas/area_2/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_2/clusters/thermal", json=["cluster_2"], ) assert res.status_code == 403, res.json() # now delete the binding constraint that references the thermal cluster in area_2 res = client.delete( - f"/v1/studies/{study_id}/bindingconstraints/bc_2", + f"/v1/studies/{internal_study_id}/bindingconstraints/bc_2", ) assert res.status_code == 200, res.json() # check that deleting the thermal cluster in area_2 succeeds res = client.delete( - f"/v1/studies/{study_id}/areas/area_2/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_2/clusters/thermal", json=["cluster_2"], ) assert res.status_code == 204, res.json() # check that deleting the thermal cluster in area_3 succeeds res = client.delete( - f"/v1/studies/{study_id}/areas/area_3/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/area_3/clusters/thermal", json=["cluster_3"], ) assert res.status_code == 204, res.json() diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index fa0d4d418c..f0eb8491f1 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -1566,7 +1566,7 @@ def set_maintenance(value: bool) -> None: assert res.json() == message -def test_import(client: TestClient, admin_access_token: str, study_id: str) -> None: +def test_import(client: TestClient, admin_access_token: str, internal_study_id: str) -> None: client.headers = {"Authorization": f"Bearer {admin_access_token}"} zip_path = ASSETS_DIR / "STA-mini.zip" @@ -1642,12 +1642,12 @@ def test_import(client: TestClient, admin_access_token: str, study_id: str) -> N # tests outputs import for .zip output_path_zip = ASSETS_DIR / "output_adq.zip" client.post( - f"/v1/studies/{study_id}/output", + f"/v1/studies/{internal_study_id}/output", headers={"Authorization": f'Bearer {george_credentials["access_token"]}'}, files={"output": io.BytesIO(output_path_zip.read_bytes())}, ) res = client.get( - f"/v1/studies/{study_id}/outputs", + f"/v1/studies/{internal_study_id}/outputs", headers={"Authorization": f'Bearer {george_credentials["access_token"]}'}, ) assert len(res.json()) == 6 @@ -1655,12 +1655,12 @@ def test_import(client: TestClient, admin_access_token: str, study_id: str) -> N # tests outputs import for .7z output_path_seven_zip = ASSETS_DIR / "output_adq.7z" client.post( - f"/v1/studies/{study_id}/output", + f"/v1/studies/{internal_study_id}/output", headers={"Authorization": f'Bearer {george_credentials["access_token"]}'}, files={"output": io.BytesIO(output_path_seven_zip.read_bytes())}, ) res = client.get( - f"/v1/studies/{study_id}/outputs", + f"/v1/studies/{internal_study_id}/outputs", headers={"Authorization": f'Bearer {george_credentials["access_token"]}'}, ) assert len(res.json()) == 7 @@ -1688,11 +1688,11 @@ def test_import(client: TestClient, admin_access_token: str, study_id: str) -> N assert result[1]["name"] == "it.txt" -def test_copy(client: TestClient, admin_access_token: str, study_id: str) -> None: +def test_copy(client: TestClient, admin_access_token: str, internal_study_id: str) -> None: client.headers = {"Authorization": f"Bearer {admin_access_token}"} # Copy a study with admin user who belongs to a group - copied = client.post(f"/v1/studies/{study_id}/copy?dest=copied&use_task=false") + copied = client.post(f"/v1/studies/{internal_study_id}/copy?dest=copied&use_task=false") assert copied.status_code == 201 # asserts that it has admin groups and PublicMode to NONE res = client.get(f"/v1/studies/{copied.json()}").json() @@ -1705,7 +1705,7 @@ def test_copy(client: TestClient, admin_access_token: str, study_id: str) -> Non # George copies a study copied = client.post( - f"/v1/studies/{study_id}/copy?dest=copied&use_task=false", + f"/v1/studies/{internal_study_id}/copy?dest=copied&use_task=false", headers={"Authorization": f'Bearer {george_credentials["access_token"]}'}, ) assert copied.status_code == 201 @@ -1715,7 +1715,9 @@ def test_copy(client: TestClient, admin_access_token: str, study_id: str) -> Non assert res["public_mode"] == "READ" -def test_areas_deletion_with_binding_constraints(client: TestClient, user_access_token: str, study_id: str) -> None: +def test_areas_deletion_with_binding_constraints( + client: TestClient, user_access_token: str, internal_study_id: str +) -> None: """ Test the deletion of areas that are referenced in binding constraints. """ @@ -1747,7 +1749,7 @@ def test_areas_deletion_with_binding_constraints(client: TestClient, user_access for constraint_term in constraint_terms: # Create an area "area_1" in the study res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={"name": area1_id.title(), "type": "AREA", "metadata": {"country": "FR"}}, ) res.raise_for_status() @@ -1755,12 +1757,12 @@ def test_areas_deletion_with_binding_constraints(client: TestClient, user_access if set(constraint_term["data"]) == {"area1", "area2"}: # Create a second area and a link between the two areas res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={"name": area2_id.title(), "type": "AREA", "metadata": {"country": "DE"}}, ) res.raise_for_status() res = client.post( - f"/v1/studies/{study_id}/links", + f"/v1/studies/{internal_study_id}/links", json={"area1": area1_id, "area2": area2_id}, ) res.raise_for_status() @@ -1768,7 +1770,7 @@ def test_areas_deletion_with_binding_constraints(client: TestClient, user_access elif set(constraint_term["data"]) == {"area", "cluster"}: # Create a cluster in the first area res = client.post( - f"/v1/studies/{study_id}/areas/{area1_id}/clusters/thermal", + f"/v1/studies/{internal_study_id}/areas/{area1_id}/clusters/thermal", json={"name": cluster_id.title(), "group": "Nuclear"}, ) res.raise_for_status() @@ -1785,7 +1787,7 @@ def test_areas_deletion_with_binding_constraints(client: TestClient, user_access "operator": "less", "terms": [constraint_term], } - res = client.post(f"/v1/studies/{study_id}/bindingconstraints", json=bc_obj) + res = client.post(f"/v1/studies/{internal_study_id}/bindingconstraints", json=bc_obj) res.raise_for_status() if set(constraint_term["data"]) == {"area1", "area2"}: @@ -1797,23 +1799,25 @@ def test_areas_deletion_with_binding_constraints(client: TestClient, user_access for area_id in areas_to_delete: # try to delete the areas - res = client.delete(f"/v1/studies/{study_id}/areas/{area_id}") + res = client.delete(f"/v1/studies/{internal_study_id}/areas/{area_id}") assert res.status_code == 403, res.json() description = res.json()["description"] assert all([elm in description for elm in [area_id, bc_id]]) assert res.json()["exception"] == "ReferencedObjectDeletionNotAllowed" # delete the binding constraint - res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/{bc_id}") + res = client.delete(f"/v1/studies/{internal_study_id}/bindingconstraints/{bc_id}") assert res.status_code == 200, res.json() for area_id in areas_to_delete: # delete the area - res = client.delete(f"/v1/studies/{study_id}/areas/{area_id}") + res = client.delete(f"/v1/studies/{internal_study_id}/areas/{area_id}") assert res.status_code == 200, res.json() -def test_links_deletion_with_binding_constraints(client: TestClient, user_access_token: str, study_id: str) -> None: +def test_links_deletion_with_binding_constraints( + client: TestClient, user_access_token: str, internal_study_id: str +) -> None: """ Test the deletion of links that are referenced in binding constraints. """ @@ -1823,7 +1827,7 @@ def test_links_deletion_with_binding_constraints(client: TestClient, user_access # Create an area "area_1" in the study res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={ "name": "area_1", "type": "AREA", @@ -1834,7 +1838,7 @@ def test_links_deletion_with_binding_constraints(client: TestClient, user_access # Create an area "area_2" in the study res = client.post( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", json={ "name": "area_2", "type": "AREA", @@ -1845,7 +1849,7 @@ def test_links_deletion_with_binding_constraints(client: TestClient, user_access # create a link between the two areas res = client.post( - f"/v1/studies/{study_id}/links", + f"/v1/studies/{internal_study_id}/links", json={"area1": "area_1", "area2": "area_2"}, ) assert res.status_code == 200, res.json() @@ -1864,20 +1868,20 @@ def test_links_deletion_with_binding_constraints(client: TestClient, user_access } ], } - res = client.post(f"/v1/studies/{study_id}/bindingconstraints", json=bc_obj) + res = client.post(f"/v1/studies/{internal_study_id}/bindingconstraints", json=bc_obj) assert res.status_code == 200, res.json() # try to delete the link before deleting the binding constraint - res = client.delete(f"/v1/studies/{study_id}/links/area_1/area_2") + res = client.delete(f"/v1/studies/{internal_study_id}/links/area_1/area_2") assert res.status_code == 403, res.json() description = res.json()["description"] assert all([elm in description for elm in ["area_1%area_2", "bc_1"]]) assert res.json()["exception"] == "ReferencedObjectDeletionNotAllowed" # delete the binding constraint - res = client.delete(f"/v1/studies/{study_id}/bindingconstraints/bc_1") + res = client.delete(f"/v1/studies/{internal_study_id}/bindingconstraints/bc_1") assert res.status_code == 200, res.json() # delete the link - res = client.delete(f"/v1/studies/{study_id}/links/area_1/area_2") + res = client.delete(f"/v1/studies/{internal_study_id}/links/area_1/area_2") assert res.status_code == 200, res.json() diff --git a/tests/integration/test_studies_upgrade.py b/tests/integration/test_studies_upgrade.py index f734223344..3eb92522af 100644 --- a/tests/integration/test_studies_upgrade.py +++ b/tests/integration/test_studies_upgrade.py @@ -11,9 +11,9 @@ class TestStudyUpgrade: @pytest.mark.skipif(RUN_ON_WINDOWS, reason="This test runs randomly on Windows") - def test_upgrade_study__next_version(self, client: TestClient, user_access_token: str, study_id: str): + def test_upgrade_study__next_version(self, client: TestClient, user_access_token: str, internal_study_id: str): res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, ) assert res.status_code == 200 @@ -24,10 +24,10 @@ def test_upgrade_study__next_version(self, client: TestClient, user_access_token assert "710" in task.result.message, f"Version not in {task.result.message=}" @pytest.mark.skipif(RUN_ON_WINDOWS, reason="This test runs randomly on Windows") - def test_upgrade_study__target_version(self, client: TestClient, user_access_token: str, study_id: str): + def test_upgrade_study__target_version(self, client: TestClient, user_access_token: str, internal_study_id: str): target_version = "720" res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, params={"target_version": target_version}, ) @@ -39,10 +39,12 @@ def test_upgrade_study__target_version(self, client: TestClient, user_access_tok assert target_version in task.result.message, f"Version not in {task.result.message=}" @pytest.mark.skipif(RUN_ON_WINDOWS, reason="This test runs randomly on Windows") - def test_upgrade_study__bad_target_version(self, client: TestClient, user_access_token: str, study_id: str): + def test_upgrade_study__bad_target_version( + self, client: TestClient, user_access_token: str, internal_study_id: str + ): target_version = "999" res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, params={"target_version": target_version}, ) diff --git a/tests/integration/variant_blueprint/test_renewable_cluster.py b/tests/integration/variant_blueprint/test_renewable_cluster.py index 3dab4a946b..e518244ff9 100644 --- a/tests/integration/variant_blueprint/test_renewable_cluster.py +++ b/tests/integration/variant_blueprint/test_renewable_cluster.py @@ -21,7 +21,7 @@ def test_lifecycle( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: # sourcery skip: extract-duplicate-method @@ -32,7 +32,7 @@ def test_lifecycle( # We have an "old" study that we need to upgrade to version 810 min_study_version = 810 res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, params={"target_version": min_study_version}, ) @@ -51,7 +51,7 @@ def test_lifecycle( "data": {"renewable-generation-modelling": "clusters"}, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "update_config", "args": args}], ) @@ -76,7 +76,7 @@ def test_lifecycle( }, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "create_renewables_cluster", "args": args}], ) @@ -97,7 +97,7 @@ def test_lifecycle( }, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "create_renewables_cluster", "args": args}], ) @@ -105,7 +105,7 @@ def test_lifecycle( # Check the properties of the renewable clusters in the "FR" area res = client.get( - f"/v1/studies/{study_id}/areas/{area_fr_id}/clusters/renewable/{cluster_fr1_id}", + f"/v1/studies/{internal_study_id}/areas/{area_fr_id}/clusters/renewable/{cluster_fr1_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -122,7 +122,7 @@ def test_lifecycle( assert properties == expected res = client.get( - f"/v1/studies/{study_id}/areas/{area_fr_id}/clusters/renewable/{cluster_fr2_id}", + f"/v1/studies/{internal_study_id}/areas/{area_fr_id}/clusters/renewable/{cluster_fr2_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -156,7 +156,7 @@ def test_lifecycle( "matrix": values_fr2.tolist(), } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[ {"action": "replace_matrix", "args": args_fr1}, @@ -167,7 +167,7 @@ def test_lifecycle( # Check the matrices of the renewable clusters in the "FR" area res = client.get( - f"/v1/studies/{study_id}/raw?path=input/renewables/series/{area_fr_id}/{series_fr1_id}/series", + f"/v1/studies/{internal_study_id}/raw?path=input/renewables/series/{area_fr_id}/{series_fr1_id}/series", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -175,7 +175,7 @@ def test_lifecycle( assert np.array(matrix_fr1["data"], dtype=np.float64).all() == values_fr1.all() res = client.get( - f"/v1/studies/{study_id}/raw?path=input/renewables/series/{area_fr_id}/{series_fr2_id}/series", + f"/v1/studies/{internal_study_id}/raw?path=input/renewables/series/{area_fr_id}/{series_fr2_id}/series", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -202,14 +202,14 @@ def test_lifecycle( }, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "create_renewables_cluster", "args": args}], ) res.raise_for_status() res = client.get( - f"/v1/studies/{study_id}/areas/{area_it_id}/clusters/renewable/{cluster_it1_id}", + f"/v1/studies/{internal_study_id}/areas/{area_it_id}/clusters/renewable/{cluster_it1_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -228,7 +228,7 @@ def test_lifecycle( # Check the matrices of the renewable clusters in the "IT" area series_it1_id = cluster_it1_id.lower() # Series IDs are in lower case res = client.get( - f"/v1/studies/{study_id}/raw?path=input/renewables/series/{area_it_id}/{series_it1_id}/series", + f"/v1/studies/{internal_study_id}/raw?path=input/renewables/series/{area_it_id}/{series_it1_id}/series", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -242,7 +242,7 @@ def test_lifecycle( # The `remove_renewables_cluster` command allows you to delete a Renewable Cluster. args = {"area_id": area_fr_id, "cluster_id": cluster_fr2_id} res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "remove_renewables_cluster", "args": args}], ) @@ -250,7 +250,7 @@ def test_lifecycle( # Check the properties of all renewable clusters res = client.get( - f"/v1/studies/{study_id}/raw?path=input/renewables/clusters&depth=4", + f"/v1/studies/{internal_study_id}/raw?path=input/renewables/clusters&depth=4", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -284,7 +284,7 @@ def test_lifecycle( # The `remove_renewables_cluster` command allows you to delete a Renewable Cluster. args = {"area_id": area_fr_id, "cluster_id": cluster_fr1_id} res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "remove_renewables_cluster", "args": args}], ) @@ -292,7 +292,7 @@ def test_lifecycle( # Check the properties of all renewable clusters res = client.get( - f"/v1/studies/{study_id}/raw?path=input/renewables/clusters&depth=4", + f"/v1/studies/{internal_study_id}/raw?path=input/renewables/clusters&depth=4", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -319,7 +319,7 @@ def test_lifecycle( # this behavior is not yet implemented, so you will encounter a 500 error. args = {"area_id": area_fr_id, "cluster_id": cluster_fr2_id} res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "remove_renewables_cluster", "args": args}], ) diff --git a/tests/integration/variant_blueprint/test_st_storage.py b/tests/integration/variant_blueprint/test_st_storage.py index c0f531ddb4..c28af6790d 100644 --- a/tests/integration/variant_blueprint/test_st_storage.py +++ b/tests/integration/variant_blueprint/test_st_storage.py @@ -22,7 +22,7 @@ def test_lifecycle( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ): # ======================= # Study version upgrade @@ -31,7 +31,7 @@ def test_lifecycle( # We have an "old" study that we need to upgrade to version 860 min_study_version = 860 res = client.put( - f"/v1/studies/{study_id}/upgrade", + f"/v1/studies/{internal_study_id}/upgrade", headers={"Authorization": f"Bearer {user_access_token}"}, params={"target_version": min_study_version}, ) @@ -42,12 +42,12 @@ def test_lifecycle( # We can check that the study is upgraded to the required version res = client.get( - f"/v1/studies/{study_id}", + f"/v1/studies/{internal_study_id}", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() assert res.json() == { - "id": study_id, + "id": internal_study_id, "name": "STA-mini", "version": min_study_version, "created": ANY, # ISO8601 Date/time @@ -69,7 +69,7 @@ def test_lifecycle( # Here is the list of available areas res = client.get( - f"/v1/studies/{study_id}/areas", + f"/v1/studies/{internal_study_id}/areas", headers={"Authorization": f"Bearer {user_access_token}"}, ) res.raise_for_status() @@ -104,7 +104,7 @@ def test_lifecycle( }, } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "create_st_storage", "args": args}], ) @@ -130,7 +130,7 @@ def test_lifecycle( "matrix": pmax_injection.tolist(), } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[ {"action": "replace_matrix", "args": args1}, @@ -166,7 +166,7 @@ def test_lifecycle( "inflows": inflows.tolist(), } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "create_st_storage", "args": args}], ) @@ -179,7 +179,7 @@ def test_lifecycle( # The `remove_st_storage` command allows you to delete a Short-Term Storage. args = {"area_id": area_id, "storage_id": siemens_battery_id} res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "remove_st_storage", "args": args}], ) @@ -215,7 +215,7 @@ def test_lifecycle( "inflows": inflows.tolist(), } res = client.post( - f"/v1/studies/{study_id}/commands", + f"/v1/studies/{internal_study_id}/commands", headers={"Authorization": f"Bearer {user_access_token}"}, json=[{"action": "create_st_storage", "args": args}], ) diff --git a/tests/integration/variant_blueprint/test_thermal_cluster.py b/tests/integration/variant_blueprint/test_thermal_cluster.py index 567b974a80..245fd8a02a 100644 --- a/tests/integration/variant_blueprint/test_thermal_cluster.py +++ b/tests/integration/variant_blueprint/test_thermal_cluster.py @@ -43,7 +43,7 @@ def test_cascade_update( self, client: TestClient, user_access_token: str, - study_id: str, + internal_study_id: str, ) -> None: """ This test is based on the study "STA-mini.zip", which is a RAW study. @@ -54,7 +54,7 @@ def test_cascade_update( """ # First, we create a copy of the study, and we convert it to a managed study. res = client.post( - f"/v1/studies/{study_id}/copy", + f"/v1/studies/{internal_study_id}/copy", headers={"Authorization": f"Bearer {user_access_token}"}, params={"dest": "default", "with_outputs": False, "use_task": False}, ) From 246ad42c035a4d7368be9c54c896ef28fcc19a8a Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE <43534797+laurent-laporte-pro@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:12:18 +0200 Subject: [PATCH 10/17] docs(user-guide): updating Binding Constraints Commands documentation and metadata for search (#2082) This PR makes changes to the doc of commands related to binding constraints, updating parameters and specifying the added fields or time series, as well as the versions in which they are available. Additionally, this PR introduces improvements in the metadata of User Guide articles to optimize results during full-text searches. The aim of these changes is twofold: on one hand, to provide users with up-to-date and accurate information on managing binding constraints, and on the other hand, to improve the user experience when searching for information in the User Guide. --- docs/user-guide/0-introduction.md | 14 ++++++++ docs/user-guide/1-interface.md | 18 ++++++++++ docs/user-guide/2-study.md | 17 ++++++++++ docs/user-guide/3-variant_manager.md | 50 ++++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/docs/user-guide/0-introduction.md b/docs/user-guide/0-introduction.md index 99fa5637ac..dc60974c2f 100644 --- a/docs/user-guide/0-introduction.md +++ b/docs/user-guide/0-introduction.md @@ -1,3 +1,17 @@ +--- +title: Introduction to Antares Web +author: Antares Web Team +date: 2021-10-05 +category: User Guide +tags: + + - introduction + - variant + - solver + - manager + +--- + # Introduction ![](../assets/antares.png) diff --git a/docs/user-guide/1-interface.md b/docs/user-guide/1-interface.md index ca002c205d..ab7954d693 100644 --- a/docs/user-guide/1-interface.md +++ b/docs/user-guide/1-interface.md @@ -1,3 +1,21 @@ +--- +title: User Interface +author: Antares Web Team +date: 2021-11-03 +category: User Guide +tags: + + - ui + - job + - api + - token + - variant + - matrix + - dataset + - batch + - launch +--- + # User interface ## What's new (2.5.0) diff --git a/docs/user-guide/2-study.md b/docs/user-guide/2-study.md index 12713241ef..2db09dbbf4 100644 --- a/docs/user-guide/2-study.md +++ b/docs/user-guide/2-study.md @@ -1,3 +1,20 @@ +--- +title: Study Configuration +author: Antares Web Team +date: 2023-12-21 +category: User Guide +tags: + + - configuration + - map + - network + - areas + - links + - binding-constraints + - debug + - table-mode +--- + # Study Configuration This page is dedicated to configuring the study in the Antares Web application. diff --git a/docs/user-guide/3-variant_manager.md b/docs/user-guide/3-variant_manager.md index 6762ee4c86..7e4b7fd690 100644 --- a/docs/user-guide/3-variant_manager.md +++ b/docs/user-guide/3-variant_manager.md @@ -1,3 +1,17 @@ +--- +title: Variant Manager +author: Antares Web Team +date: 2021-10-29 +category: User Guide +tags: + + - variant + - manager + - configuration + - command + - API +--- + # Variant Manager ## Introduction @@ -222,9 +236,15 @@ Create a new binding constraint "enabled?": " (default: True)", "time_step": "'hourly' | 'weekly' | 'daily'", "operator": "'equal' | 'both' | 'greater' | 'less'", + "comments?": "", + "group?": "", + "filter_year_by_year?": "", + "filter_synthesis?": "", "coeffs": "", "values?": "", - "comments?": "" + "less_term_matrix?": "", + "greater_term_matrix?": "", + "equal_term_matrix?": "" } ``` @@ -250,6 +270,20 @@ Or link `CONSTRAINT_COEFF` is: } ``` +> **Available Since v8.3:** +> +> The `filter_year_by_year` and `filter_synthesis` fields are only available for studies since v8.3. +> Those fields are used for the Geographic Trimming. +> Possible values are on or several of the following: "hourly", "daily", "weekly", "monthly", "annual". + +> **Available Since v8.7:** +> +> The `group` fields and the `less_term_matrix`, `greater_term_matrix`, `equal_term_matrix` time series fields +> are available since v8.7. +> The `group` field is used to group constraints in the Monte Carlo Scenario Builder (default is `default`). +> The time series matrices are used to define the Right-Hand Side (RHS) of the binding constraint. +> Note that the `values` field must not be used when using the time series matrices. + ### `update_binding_constraint` Update an existing binding constraint @@ -260,12 +294,20 @@ Update an existing binding constraint "enabled?": " (default: True)", "time_step": "'hourly' | 'weekly' | 'daily'", "operator": "'equal' | 'both' | 'greater' | 'less'", + "comments?": "", + "group?": "", + "filter_year_by_year?": "", + "filter_synthesis?": "", "coeffs": "", "values?": "", - "comments?": "" + "less_term_matrix?": "", + "greater_term_matrix?": "", + "equal_term_matrix?": "" } ``` +See [create_binding_constraint](#create_binding_constraint) for the details of the fields. + ### `remove_binding_constraint` Remove an existing binding constraint @@ -325,6 +367,8 @@ Replace arbitrary data file (must not be a matrix or ini target) with a base64 e ### `create_st_storage` +> **Available Since v8.6** + Create a new short-term storage ```json @@ -341,6 +385,8 @@ Create a new short-term storage ### `remove_st_storage` +> **Available Since v8.6** + Remove an existing short-term storage ```json From a2ac0828ca45d373a1c8dc3d9fb26a60e6cfe65c Mon Sep 17 00:00:00 2001 From: Laurent LAPORTE <43534797+laurent-laporte-pro@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:00:41 +0200 Subject: [PATCH 11/17] docs(user-guide): improve the user guide and add "How to Create a New Study?" topic (#2081) --- .../media/how-to/study-create-button.png | Bin 0 -> 255057 bytes .../assets/media/how-to/study-create-form.png | Bin 0 -> 26798 bytes .../how-to/study-create-other-options.png | Bin 0 -> 40692 bytes .../how-to/study-creation-edit-properties.png | Bin 0 -> 25812 bytes .../study-creation-move-to-subfolder.png | Bin 0 -> 10729 bytes docs/how-to/studies-create.md | 160 ++++++++++++++++++ docs/how-to/studies-import.md | 45 +++-- docs/how-to/studies-upgrade.md | 18 +- docs/index.md | 57 ++++--- docs/user-guide/0-introduction.md | 42 +++-- docs/user-guide/1-interface.md | 51 +++--- docs/user-guide/3-variant_manager.md | 2 +- mkdocs.yml | 1 + 13 files changed, 296 insertions(+), 80 deletions(-) create mode 100644 docs/assets/media/how-to/study-create-button.png create mode 100644 docs/assets/media/how-to/study-create-form.png create mode 100644 docs/assets/media/how-to/study-create-other-options.png create mode 100644 docs/assets/media/how-to/study-creation-edit-properties.png create mode 100644 docs/assets/media/how-to/study-creation-move-to-subfolder.png create mode 100644 docs/how-to/studies-create.md diff --git a/docs/assets/media/how-to/study-create-button.png b/docs/assets/media/how-to/study-create-button.png new file mode 100644 index 0000000000000000000000000000000000000000..fb149407cca930ca46b617fbca506705c6b34519 GIT binary patch literal 255057 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