diff --git a/.eslintrc.json b/.eslintrc.json index 0b5cb28..e740de0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,4 +1,21 @@ { - "extends": ["@exabyte-io/eslint-config"] + "extends": [ + "@exabyte-io/eslint-config" + ], + "ignorePatterns": [ + "dist/", + "src/workflows/workflows.js" + ], + "settings": { + "import/resolver": { + "node": { + "extensions": [ + ".js", + ".jsx", + ".ts", + ".tsx" + ] + } + } + } } - diff --git a/package-lock.json b/package-lock.json index c5b3d6b..faea4bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,8 @@ "@babel/preset-react": "7.16.7", "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", + "@exabyte-io/periodic-table.js": "2022.6.8-0", + "crypto-js": "^4.2.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mixwith": "^0.1.1", @@ -25,14 +27,14 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "2025.5.5-0", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", "@exabyte-io/application-flavors.js": "2025.5.10-0", - "@exabyte-io/eslint-config": "^2022.11.17-0", + "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "2025.4.27-0", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "2025.4.30-0", + "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", @@ -2256,6 +2258,51 @@ "node": ">=12.0.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -2335,26 +2382,16 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/@exabyte-io/ade.js": { - "version": "2025.5.5-0", - "resolved": "https://registry.npmjs.org/@exabyte-io/ade.js/-/ade.js-2025.5.5-0.tgz", - "integrity": "sha512-tMcToIDpo73Dm0KBITFJ1kFRLtWD+sRnG4wBX99XhRd+i/GxFca58SFUUcB+1axql862PPmhA90cvBnyAY6/7Q==", + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", + "integrity": "sha512-uhFBtkZN1rXnUwbhD7ntzDxsnuYQdacmXbZxyy6cjV4vctRmwkDUIrZ3hn7FapNaBxLi8xHz0xMYycBxTpYF8g==", "dev": true, - "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "@babel/cli": "7.16.0", - "@babel/core": "7.16.0", - "@babel/eslint-parser": "7.16.3", - "@babel/plugin-proposal-class-properties": "7.16.0", - "@babel/preset-env": "7.16.4", - "@babel/preset-react": "7.16.7", - "@babel/register": "^7.16.0", - "@babel/runtime-corejs3": "7.16.8", - "@exabyte-io/periodic-table.js": "2022.6.8-0", + "@types/react-jsonschema-form": "^1.7.13", "lodash": "^4.17.21", - "mixwith": "^0.1.1", "nunjucks": "^3.2.4", - "underscore": "^1.13.3", - "underscore.string": "^3.3.4" + "react-jsonschema-form": "^1.8.1" }, "engines": { "node": ">=12.0.0" @@ -2453,32 +2490,38 @@ } }, "node_modules/@exabyte-io/eslint-config": { - "version": "2022.11.17-0", - "resolved": "https://registry.npmjs.org/@exabyte-io/eslint-config/-/eslint-config-2022.11.17-0.tgz", - "integrity": "sha512-BYTDSqvjj6ZiWb8l46T5BKrVfkelct+vK2mh7joHu5UWtJMUzLkb0KQMV1+6SUy4xHFnws33XS7/+JSW1yeZOQ==", + "version": "2025.5.13-0", + "resolved": "https://registry.npmjs.org/@exabyte-io/eslint-config/-/eslint-config-2025.5.13-0.tgz", + "integrity": "sha512-uZcq9jzmDHl+N71GYEM7l0z6mwyYfuZdNA/bIyql6Mp2H++Oot62nIoMhgvds1r7dbrtL/3jD3Xv0YDj12NiYw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.0.0" }, "peerDependencies": { - "@babel/eslint-parser": "7.16.3", - "@babel/plugin-proposal-class-properties": "7.16.0", - "@babel/preset-env": "7.16.4", - "@babel/preset-react": "7.16.7", + "@babel/eslint-parser": "^7.16.3", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.7", "@babel/register": "^7.16.0", - "@babel/runtime-corejs3": "7.16.8", - "eslint": "7.32.0", - "eslint-config-airbnb": "19.0.2", + "@babel/runtime-corejs3": "^7.16.8", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "@typescript-eslint/parser": "^5.56.0", + "eslint": "^7.32.0", + "eslint-config-airbnb": "^19.0.2", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-exports": "^1.0.0-beta.2", "eslint-import-resolver-meteor": "^0.4.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-plugin-import": "2.25.3", - "eslint-plugin-jsdoc": "37.1.0", - "eslint-plugin-jsx-a11y": "6.5.1", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsdoc": "^37.1.0 || ^50.6.0", + "eslint-plugin-jsonc": "^2.12.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-mui-path-imports": "^0.0.15", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "7.30.0", - "eslint-plugin-simple-import-sort": "7.0.0" + "eslint-plugin-react": "^7.30.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "jsonc-eslint-parser": "^2.1.0" } }, "node_modules/@exabyte-io/ide.js": { @@ -2543,7 +2586,6 @@ "version": "2022.6.8-0", "resolved": "https://registry.npmjs.org/@exabyte-io/periodic-table.js/-/periodic-table.js-2022.6.8-0.tgz", "integrity": "sha512-tN9V+Q6AUo/RVn9qrgx4dV+1VI5GbBjwJGbx4+K+zIw2W8Rnwp2l22lj123Xj9wdFLpygyPruETCM04XJkPNuw==", - "dev": true, "hasInstallScript": true, "dependencies": { "@babel/cli": "7.16.0", @@ -2562,7 +2604,6 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.16.0.tgz", "integrity": "sha512-lzl4yfs0zVXnooeLE0AAfYaT7F3SPA8yB2Bj4W1BiZwLbMS3MZH35ZvCWSRHvneUugwuM+Wsnrj7h0F7UmU3NQ==", - "dev": true, "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -2580,8 +2621,7 @@ "node_modules/@exabyte-io/periodic-table.js/node_modules/underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==", - "dev": true + "integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", @@ -2770,10 +2810,11 @@ "dev": true }, "node_modules/@mat3ra/code": { - "version": "2025.4.27-0", - "resolved": "https://registry.npmjs.org/@mat3ra/code/-/code-2025.4.27-0.tgz", - "integrity": "sha512-v4fewXJEImCBh716z/hmI9GqU2JVl1XUYjUbvgZ3pYwxph1g1nU+H7DgRHu415t8ByJsjdLVkgkBlYU4+m/HSw==", + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", + "integrity": "sha512-w/v9+NRIZkRt6Ov5jBVowGmxnuAv1JrXMOderAZd9kVqTEvDMcPpImd1NV1VQTHG8xy7Uq2piRS0a15SyyVh6Q==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@types/mathjs": "^5.0.1", "crypto-js": "^4.2.0", @@ -2783,7 +2824,6 @@ "mathjs": "^5.10.3", "mixwith": "^0.1.1", "nunjucks": "^3.2.4", - "react-jsonschema-form": "^1.8.1", "semver": "^7.6.3", "underscore": "^1.13.7", "underscore.string": "^3.3.6", @@ -3155,10 +3195,11 @@ } }, "node_modules/@mat3ra/made": { - "version": "2025.4.30-0", - "resolved": "https://registry.npmjs.org/@mat3ra/made/-/made-2025.4.30-0.tgz", - "integrity": "sha512-vuXirZpSXEE77eqnUkS6+PyjPTfauCm0mc7FMIUggVN4Swi69t9COpd16IWe05DCtWSrzGebPbz+Bsqm77w9sg==", + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", + "integrity": "sha512-c+QC8p72ENTbRdx1aQOpP/soLLcnzF6P3uXf9cQicVeZ8H+IJpnvU3ORpMkPFWn4VZ5mU32EDqqnrRc4kXK+0A==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@babel/core": "7.24.1", "@exabyte-io/periodic-table.js": "2022.5.28-0", @@ -3322,6 +3363,61 @@ "eslint-scope": "5.1.1" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", + "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.10.tgz", @@ -3440,6 +3536,35 @@ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", "dev": true }, + "node_modules/@types/react": { + "version": "19.1.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", + "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-jsonschema-form": { + "version": "1.7.13", + "resolved": "https://registry.npmjs.org/@types/react-jsonschema-form/-/react-jsonschema-form-1.7.13.tgz", + "integrity": "sha512-C2jgO7/ow76oCSfUK++jKKox17R0A7ryMYNE5hJ2dR1Ske9jhuvjIlurvzMePh+Xjk8wey0nzB2C7HFKe2pRdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "*", + "@types/react": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/underscore": { "version": "1.11.15", "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.15.tgz", @@ -3455,6 +3580,277 @@ "@types/underscore": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -3468,9 +3864,10 @@ "dev": true }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3712,6 +4109,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -3897,12 +4305,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "devOptional": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4444,7 +4853,14 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", - "dev": true + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" }, "node_modules/d": { "version": "1.0.2", @@ -4637,6 +5053,20 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -4941,6 +5371,37 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-compat-utils": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", + "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-config-airbnb": { "version": "19.0.2", "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.2.tgz", @@ -5049,6 +5510,29 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-json-compat-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", + "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esquery": "^1.6.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": "*", + "jsonc-eslint-parser": "^2.4.0" + }, + "peerDependenciesMeta": { + "@eslint/json": { + "optional": true + } + } + }, "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", @@ -5197,6 +5681,66 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/eslint-plugin-jsonc": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.20.1.tgz", + "integrity": "sha512-gUzIwQHXx7ZPypUoadcyRi4WbHW2TPixDr0kqQ4miuJBU0emJmyGTlnaT3Og9X2a8R1CDayN9BFSq5weGWbTng==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.1", + "eslint-compat-utils": "^0.6.4", + "eslint-json-compat-utils": "^0.2.1", + "espree": "^9.6.1 || ^10.3.0", + "graphemer": "^1.4.0", + "jsonc-eslint-parser": "^2.4.0", + "natural-compare": "^1.4.0", + "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-jsonc/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-jsonc/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", @@ -5229,6 +5773,23 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/eslint-plugin-mui-path-imports": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/eslint-plugin-mui-path-imports/-/eslint-plugin-mui-path-imports-0.0.15.tgz", + "integrity": "sha512-u61kgRBtUAG+zoApuf8oWuW6mf3SIfrpMq/gSQEM2h/3qzkqvWXB4RRmPzVryS6bpeXT0QsW8rFcdcMVnoz0hw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "requireindex": "^1.2.0" + }, + "engines": { + "node": "12.x || 14.x || >= 16" + }, + "peerDependencies": { + "eslint": ">=6" + } + }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -5621,9 +6182,10 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -5727,6 +6289,24 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5752,6 +6332,17 @@ } ] }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5764,10 +6355,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6108,6 +6700,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -6126,6 +6762,14 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -6548,6 +7192,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -7085,6 +7730,73 @@ "node": ">=6" } }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", + "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -7609,13 +8321,25 @@ "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", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -8002,6 +8726,14 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -8597,6 +9329,17 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -8751,6 +9494,28 @@ "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -8978,6 +9743,17 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.5" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -9024,6 +9800,18 @@ "node": ">=8" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rfdc": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", @@ -9045,6 +9833,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -9530,6 +10343,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", + "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@pkgr/core": "^0.2.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -9612,6 +10442,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "devOptional": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -9728,6 +10559,31 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD", + "peer": true + }, "node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", diff --git a/package.json b/package.json index 3c68d79..b735c48 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,8 @@ "@babel/preset-react": "7.16.7", "@babel/register": "^7.16.0", "@babel/runtime-corejs3": "7.16.8", + "@exabyte-io/periodic-table.js": "2022.6.8-0", + "crypto-js": "^4.2.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mixwith": "^0.1.1", @@ -46,14 +48,14 @@ "underscore.string": "^3.3.4" }, "devDependencies": { - "@exabyte-io/ade.js": "2025.5.5-0", + "@exabyte-io/ade.js": "git+https://github.com/Exabyte-io/ade.js.git#bbb62dc12f4ae7c4ba32edc60e459b8bbbcd232d", "@exabyte-io/application-flavors.js": "2025.5.10-0", - "@exabyte-io/eslint-config": "^2022.11.17-0", + "@exabyte-io/eslint-config": "2025.5.13-0", "@exabyte-io/ide.js": "2024.3.26-0", "@exabyte-io/mode.js": "2024.4.28-0", - "@mat3ra/code": "2025.4.27-0", + "@mat3ra/code": "git+https://github.com/Exabyte-io/code.git#3fbf30e5318c9f1ab7a3a5b967fa57d2b70cad3e", "@mat3ra/esse": "2025.4.26-0", - "@mat3ra/made": "2025.4.30-0", + "@mat3ra/made": "git+https://github.com/Exabyte-io/made.git#84807b83b15dfd632fae9495be301aa7df503b11", "chai": "^4.3.4", "eslint": "7.32.0", "eslint-config-airbnb": "19.0.2", diff --git a/src/context/context.js b/src/context/context.js index 082bc1e..86a6eb0 100644 --- a/src/context/context.js +++ b/src/context/context.js @@ -1,4 +1,9 @@ import { BoundaryConditionsFormDataProvider } from "./providers/BoundaryConditionsFormDataProvider"; +import QENEBContextProvider from "./providers/by_application/espresso/QENEBContextProvider"; +import QEPWXContextProvider from "./providers/by_application/espresso/QEPWXContextProvider"; +import NWChemTotalEnergyContextProvider from "./providers/by_application/nwchem/NWChemTotalEnergyContextProvider"; +import VASPContextProvider from "./providers/by_application/vasp/VASPContextProvider"; +import VASPNEBContextProvider from "./providers/by_application/vasp/VASPNEBContextProvider"; import { CollinearMagnetizationContextProvider } from "./providers/CollinearMagnetizationContextProvider"; import { HubbardContextProviderLegacy } from "./providers/HubbardContextProviderLegacy"; import { HubbardJContextProvider } from "./providers/HubbardJContextProvider"; @@ -34,4 +39,9 @@ export default { IonDynamicsContextProvider, CollinearMagnetizationContextProvider, NonCollinearMagnetizationContextProvider, + VASPContextProvider, + VASPNEBContextProvider, + QEPWXContextProvider, + QENEBContextProvider, + NWChemTotalEnergyContextProvider, }; diff --git a/src/context/mixins/ApplicationContextMixin.js b/src/context/mixins/ApplicationContextMixin.js new file mode 100644 index 0000000..76484ad --- /dev/null +++ b/src/context/mixins/ApplicationContextMixin.js @@ -0,0 +1,19 @@ +import { globalSettings } from "../providers/settings"; + +export function applicationContextMixin(item) { + const properties = { + _application: undefined, + + initApplicationContextMixin() { + this._application = + (this.config.context && this.config.context.application) || + globalSettings.Application.createDefault(); + }, + + get application() { + return this._application; + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/JobContextMixin.js b/src/context/mixins/JobContextMixin.js new file mode 100644 index 0000000..19213fe --- /dev/null +++ b/src/context/mixins/JobContextMixin.js @@ -0,0 +1,36 @@ +const defaultJob = { + workflow: { + subworkflows: [], + units: [], + }, + status: "pre-submission", + compute: { + queue: "D", + nodes: 1, + ppn: 1, + timeLimit: "3600", + }, + _project: { + _id: "", + }, +}; + +export function jobContextMixin(item) { + const properties = { + isEdited: false, + + _job: defaultJob, + + get job() { + return this._job; + }, + + initJobContextMixin() { + const { config } = this; + this._job = (config.context && config.context.job) || defaultJob; + this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MaterialContextMixin.js b/src/context/mixins/MaterialContextMixin.js new file mode 100644 index 0000000..6c0d653 --- /dev/null +++ b/src/context/mixins/MaterialContextMixin.js @@ -0,0 +1,41 @@ +import { globalSettings } from "../providers/settings"; + +export function materialContextMixin(item) { + const properties = { + _material: undefined, + + updateMaterialHash() { + if (this.isEditedIsSetToFalseOnMaterialUpdate) this.isEdited = false; + this.extraData = { materialHash: this.material.hash }; + }, + + // Workaround: Material.createDefault() used to initiate workflow reducer and hence here too + // does not have an id. Here we catch when such material is used and avoid resetting isEdited + get isMaterialCreatedDefault() { + return !this.material.id; + }, + + get isMaterialUpdated() { + return Boolean(this.extraData && this.extraData.materialHash !== this.material.hash); + }, + + get material() { + if (!this._material) { + throw new Error("Material is not set"); + } + return this._material; + }, + + initMaterialContextMixin() { + this._material = this.config.context && this.config.context.material; + + if (!this._material) { + this._material = globalSettings.Material.createDefault(); + } + + this.updateMaterialHash(); + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MaterialsContextMixin.js b/src/context/mixins/MaterialsContextMixin.js new file mode 100644 index 0000000..9ebc2e5 --- /dev/null +++ b/src/context/mixins/MaterialsContextMixin.js @@ -0,0 +1,18 @@ +import { globalSettings } from "../providers/settings"; + +export function materialsContextMixin(item) { + const properties = { + get materials() { + return this._materials; + }, + initMaterialsContextMixin() { + const materials = this.config.context?.materials; + this._materials = + materials && materials.length + ? materials + : [globalSettings.Material.createDefault()]; + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MaterialsSetContextMixin.js b/src/context/mixins/MaterialsSetContextMixin.js new file mode 100644 index 0000000..35bef4f --- /dev/null +++ b/src/context/mixins/MaterialsSetContextMixin.js @@ -0,0 +1,24 @@ +import { compareEntitiesInOrderedSetForSorting } from "@mat3ra/code/dist/js/entity/set/ordered/utils"; + +export function materialsSetContextMixin(item) { + const properties = { + _materialsSet: undefined, + + get materialsSet() { + return this._materialsSet; + }, + + initMaterialsSetContextMixin() { + this._materialsSet = this.config.context?.materialsSet; + }, + + sortMaterialsByIndexInSet(materials = []) { + // DO NOT SORT IN PLACE AS IT CHANGES THE ORDER IN `this.materials` AND HAS SIDE EFFECTS (MaterialViewer). + return materials.concat().sort((a, b) => { + return compareEntitiesInOrderedSetForSorting(a, b, this.materialsSet._id, false); + }); + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/MethodDataContextMixin.js b/src/context/mixins/MethodDataContextMixin.js new file mode 100644 index 0000000..4443de2 --- /dev/null +++ b/src/context/mixins/MethodDataContextMixin.js @@ -0,0 +1,48 @@ +import CryptoJS from "crypto-js"; + +export function methodDataContextMixin(item) { + const properties = { + _methodData: undefined, + + isEdited: false, + + methodDataHash: undefined, + + extraData: undefined, + + initMethodDataContextMixin() { + this._methodData = (this.config.context && this.config.context.methodData) || {}; + this.isEdited = Boolean(this.config.isEdited); + }, + + /* @summary Replace the logic in constructor with this in order to enable passing `methodDataHash` between + * subsequent initializations of the derived class. Not used at present and kept for the record. + */ + _initMethodDataHash() { + this.methodDataHash = CryptoJS.MD5(JSON.stringify(this.methodData)).toString(); + this.extraData = { methodDataHash: this.methodDataHash }; + if (!this._methodData) { + this._methodData = {}; + this.isEdited = false; + // Commented out to reduce effect on performance. Uncomment for debugging purposes. + // TODO: remove on next refactoring or convert to log + // console.warn("MethodDataContextMixin: methodData is undefined or null"); + } else if (this.isMethodDataUpdated) { + this.isEdited = false; + } else { + // eslint-disable-next-line no-undef + this.isEdited = config.isEdited; + } + }, + + get methodData() { + return this._methodData; + }, + + get isMethodDataUpdated() { + return Boolean(this.extraData && this.extraData.methodDataHash !== this.methodDataHash); + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/mixins/WorkflowContextMixin.js b/src/context/mixins/WorkflowContextMixin.js new file mode 100644 index 0000000..c66c290 --- /dev/null +++ b/src/context/mixins/WorkflowContextMixin.js @@ -0,0 +1,25 @@ +const defaultWorkflow = { + subworkflows: [], + units: [], + hasRelaxation: false, +}; + +export function workflowContextMixin(item) { + const properties = { + isEdited: false, + + _workflow: defaultWorkflow, + + get workflow() { + return this._workflow; + }, + + initWorkflowContextMixin() { + const { config } = this; // as WorkflowConfig; + this._workflow = (config.context && config.context.workflow) || defaultWorkflow; + this.isEdited = false; // we always get the `defaultData` (recalculated from scratch, not persistent) + }, + }; + + Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties)); +} diff --git a/src/context/providers.js b/src/context/providers.js index 94e4383..34157b3 100644 --- a/src/context/providers.js +++ b/src/context/providers.js @@ -17,6 +17,11 @@ const { IonDynamicsContextProvider, CollinearMagnetizationContextProvider, NonCollinearMagnetizationContextProvider, + VASPContextProvider, + VASPNEBContextProvider, + QEPWXContextProvider, + QENEBContextProvider, + NWChemTotalEnergyContextProvider, } = context; const CONTEXT_DOMAINS = { @@ -112,4 +117,24 @@ export const wodeProviders = { providerCls: NonCollinearMagnetizationContextProvider, config: _makeImportant({ name: "nonCollinearMagnetization" }), }, + QEPWXInputDataManager: { + providerCls: QEPWXContextProvider, + config: { name: "input" }, + }, + QENEBInputDataManager: { + providerCls: QENEBContextProvider, + config: { name: "input" }, + }, + VASPInputDataManager: { + providerCls: VASPContextProvider, + config: { name: "input" }, + }, + VASPNEBInputDataManager: { + providerCls: VASPNEBContextProvider, + config: { name: "input" }, + }, + NWChemInputDataManager: { + providerCls: NWChemTotalEnergyContextProvider, + config: { name: "input" }, + }, }; diff --git a/src/context/providers/BoundaryConditionsFormDataProvider.js b/src/context/providers/BoundaryConditionsFormDataProvider.js index c9bd6f1..79b248b 100644 --- a/src/context/providers/BoundaryConditionsFormDataProvider.js +++ b/src/context/providers/BoundaryConditionsFormDataProvider.js @@ -1,12 +1,14 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { deepClone } from "@mat3ra/code/dist/js/utils"; import { Made } from "@mat3ra/made"; -import { mix } from "mixwith"; -export class BoundaryConditionsFormDataProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { - static Material = Made.Material; +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + +export class BoundaryConditionsFormDataProvider extends JSONSchemaFormDataProvider { + constructor(config) { + super(config); + this.initMaterialContextMixin(); + } get boundaryConditions() { return this.material.metadata.boundaryConditions || {}; @@ -74,3 +76,5 @@ export class BoundaryConditionsFormDataProvider extends mix(JSONSchemaFormDataPr }; } } + +materialContextMixin(BoundaryConditionsFormDataProvider.prototype); diff --git a/src/context/providers/CollinearMagnetizationContextProvider.js b/src/context/providers/CollinearMagnetizationContextProvider.js index 71c53ff..4134c29 100644 --- a/src/context/providers/CollinearMagnetizationContextProvider.js +++ b/src/context/providers/CollinearMagnetizationContextProvider.js @@ -1,15 +1,14 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; -import { Made } from "@mat3ra/made"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import lodash from "lodash"; -import { mix } from "mixwith"; -export class CollinearMagnetizationContextProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { - static Material = Made.Material; +import { materialContextMixin } from "../mixins/MaterialContextMixin"; +export class CollinearMagnetizationContextProvider extends JSONSchemaFormDataProvider { constructor(config) { super(config); + + this.initMaterialContextMixin(); + this.firstElement = this.uniqueElementsWithLabels?.length > 0 ? this.uniqueElementsWithLabels[0] : ""; this.isTotalMagnetization = lodash.get(this.data, "isTotalMagnetization", false); @@ -114,3 +113,5 @@ export class CollinearMagnetizationContextProvider extends mix(JSONSchemaFormDat }; } } + +materialContextMixin(CollinearMagnetizationContextProvider.prototype); diff --git a/src/context/providers/HubbardUContextProvider.js b/src/context/providers/HubbardUContextProvider.js index 2324af3..20103eb 100644 --- a/src/context/providers/HubbardUContextProvider.js +++ b/src/context/providers/HubbardUContextProvider.js @@ -1,6 +1,6 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; -import { Made } from "@mat3ra/made"; -import { mix } from "mixwith"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; + +import { materialContextMixin } from "../mixins/MaterialContextMixin"; const defaultHubbardConfig = { atomicSpecies: "", @@ -8,13 +8,12 @@ const defaultHubbardConfig = { hubbardUValue: 1.0, }; -export class HubbardUContextProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { - static Material = Made.Material; - +export class HubbardUContextProvider extends JSONSchemaFormDataProvider { constructor(config) { super(config); + + this.initMaterialContextMixin(); + this.uniqueElements = this.material?.Basis?.uniqueElements || []; this.orbitalList = [ "2p", @@ -97,3 +96,5 @@ export class HubbardUContextProvider extends mix(JSONSchemaFormDataProvider).wit }; } } + +materialContextMixin(HubbardUContextProvider.prototype); diff --git a/src/context/providers/IonDynamicsContextProvider.js b/src/context/providers/IonDynamicsContextProvider.js index 097d5fe..cc82502 100644 --- a/src/context/providers/IonDynamicsContextProvider.js +++ b/src/context/providers/IonDynamicsContextProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; const defaultMDConfig = { numberOfSteps: 100, diff --git a/src/context/providers/MLSettingsContextProvider.js b/src/context/providers/MLSettingsContextProvider.js index f7360f7..e51ca21 100644 --- a/src/context/providers/MLSettingsContextProvider.js +++ b/src/context/providers/MLSettingsContextProvider.js @@ -1,9 +1,12 @@ -import { Application } from "@exabyte-io/ade.js"; -import { ApplicationContextMixin, ContextProvider } from "@mat3ra/code/dist/js/context"; -import { mix } from "mixwith"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; -export class MLSettingsContextProvider extends mix(ContextProvider).with(ApplicationContextMixin) { - static Application = Application; +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; + +export class MLSettingsContextProvider extends ContextProvider { + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } // eslint-disable-next-line class-methods-use-this get uiSchema() { @@ -41,3 +44,5 @@ export class MLSettingsContextProvider extends mix(ContextProvider).with(Applica }; } } + +applicationContextMixin(MLSettingsContextProvider.prototype); diff --git a/src/context/providers/MLTrainTestSplitContextProvider.js b/src/context/providers/MLTrainTestSplitContextProvider.js index 02d3585..5a6a001 100644 --- a/src/context/providers/MLTrainTestSplitContextProvider.js +++ b/src/context/providers/MLTrainTestSplitContextProvider.js @@ -1,11 +1,12 @@ -import { Application } from "@exabyte-io/ade.js"; -import { ApplicationContextMixin, ContextProvider } from "@mat3ra/code/dist/js/context"; -import { mix } from "mixwith"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; -export class MLTrainTestSplitContextProvider extends mix(ContextProvider).with( - ApplicationContextMixin, -) { - static Application = Application; +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; + +export class MLTrainTestSplitContextProvider extends ContextProvider { + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } // eslint-disable-next-line class-methods-use-this get uiSchema() { @@ -40,3 +41,5 @@ export class MLTrainTestSplitContextProvider extends mix(ContextProvider).with( }; } } + +applicationContextMixin(MLTrainTestSplitContextProvider.prototype); diff --git a/src/context/providers/NEBFormDataProvider.js b/src/context/providers/NEBFormDataProvider.js index e13a4ef..c89c86f 100644 --- a/src/context/providers/NEBFormDataProvider.js +++ b/src/context/providers/NEBFormDataProvider.js @@ -1,4 +1,4 @@ -import { JSONSchemaFormDataProvider } from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; export class NEBFormDataProvider extends JSONSchemaFormDataProvider { // eslint-disable-next-line class-methods-use-this diff --git a/src/context/providers/NonCollinearMagnetizationContextProvider.js b/src/context/providers/NonCollinearMagnetizationContextProvider.js index d43b82b..b5cf686 100644 --- a/src/context/providers/NonCollinearMagnetizationContextProvider.js +++ b/src/context/providers/NonCollinearMagnetizationContextProvider.js @@ -1,15 +1,12 @@ -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; -import { Made } from "@mat3ra/made"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import lodash from "lodash"; -import { mix } from "mixwith"; -export class NonCollinearMagnetizationContextProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { - static Material = Made.Material; +import { materialContextMixin } from "../mixins/MaterialContextMixin"; +export class NonCollinearMagnetizationContextProvider extends JSONSchemaFormDataProvider { constructor(config) { super(config); + this.initMaterialContextMixin(); this.isStartingMagnetization = lodash.get(this.data, "isStartingMagnetization", true); this.isConstrainedMagnetization = lodash.get( this.data, @@ -268,3 +265,5 @@ export class NonCollinearMagnetizationContextProvider extends mix(JSONSchemaForm }; } } + +materialContextMixin(NonCollinearMagnetizationContextProvider.prototype); diff --git a/src/context/providers/PlanewaveCutoffsContextProvider.js b/src/context/providers/PlanewaveCutoffsContextProvider.js index ee4249c..2b83edf 100644 --- a/src/context/providers/PlanewaveCutoffsContextProvider.js +++ b/src/context/providers/PlanewaveCutoffsContextProvider.js @@ -1,6 +1,6 @@ -import { Application } from "@exabyte-io/ade.js"; -import { ApplicationContextMixin, ContextProvider } from "@mat3ra/code/dist/js/context"; -import { mix } from "mixwith"; +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; + +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; const cutoffConfig = { vasp: {}, // assuming default cutoffs for VASP @@ -11,10 +11,11 @@ const cutoffConfig = { }, }; -export class PlanewaveCutoffsContextProvider extends mix(ContextProvider).with( - ApplicationContextMixin, -) { - static Application = Application; +export class PlanewaveCutoffsContextProvider extends ContextProvider { + constructor(config) { + super(config); + this.initApplicationContextMixin(); + } // eslint-disable-next-line class-methods-use-this get uiSchema() { @@ -63,3 +64,5 @@ export class PlanewaveCutoffsContextProvider extends mix(ContextProvider).with( }; } } + +applicationContextMixin(PlanewaveCutoffsContextProvider.prototype); diff --git a/src/context/providers/PointsGridFormDataProvider.js b/src/context/providers/PointsGridFormDataProvider.js index 8af32b6..3d47312 100644 --- a/src/context/providers/PointsGridFormDataProvider.js +++ b/src/context/providers/PointsGridFormDataProvider.js @@ -1,20 +1,17 @@ +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { units as UNITS } from "@mat3ra/code/dist/js/constants"; -import { JSONSchemaFormDataProvider, MaterialContextMixin } from "@mat3ra/code/dist/js/context"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; import lodash from "lodash"; -import { mix } from "mixwith"; -// TODO : pass appSettings to use defaultKPPRA -export class PointsGridFormDataProvider extends mix(JSONSchemaFormDataProvider).with( - MaterialContextMixin, -) { - static Material = Made.Material; - - static _defaultKPPRA = 5; +import { materialContextMixin } from "../mixins/MaterialContextMixin"; +import { globalSettings } from "./settings"; +export class PointsGridFormDataProvider extends JSONSchemaFormDataProvider { constructor(config) { super(config); + this.initMaterialContextMixin(); + this._divisor = config.divisor || 1; // KPPRA will be divided by this number this.reciprocalLattice = new Made.ReciprocalLattice(this.material.lattice); @@ -53,7 +50,7 @@ export class PointsGridFormDataProvider extends mix(JSONSchemaFormDataProvider). _getDefaultGridMetricValue(metric) { switch (metric) { case "KPPRA": - return Math.floor(PointsGridFormDataProvider._defaultKPPRA / this._divisor); + return Math.floor(globalSettings.defaultKPPRA / this._divisor); case "spacing": return 0.3; default: @@ -284,3 +281,5 @@ export class PointsGridFormDataProvider extends mix(JSONSchemaFormDataProvider). return data; } } + +materialContextMixin(PointsGridFormDataProvider.prototype); diff --git a/src/context/providers/PointsPathFormDataProvider.js b/src/context/providers/PointsPathFormDataProvider.js index de472ea..e461289 100644 --- a/src/context/providers/PointsPathFormDataProvider.js +++ b/src/context/providers/PointsPathFormDataProvider.js @@ -1,29 +1,21 @@ /* eslint-disable max-classes-per-file */ /* eslint react/prop-types: 0 */ -import { Application } from "@exabyte-io/ade.js"; -import { - ApplicationContextMixin, - JSONSchemaFormDataProvider, - MaterialContextMixin, -} from "@mat3ra/code/dist/js/context"; +import JSONSchemaFormDataProvider from "@exabyte-io/ade.js/dist/js/context/JSONSchemaFormDataProvider"; import { math as codeJSMath } from "@mat3ra/code/dist/js/math"; import { Made } from "@mat3ra/made"; -import { mix } from "mixwith"; import s from "underscore.string"; +import { applicationContextMixin } from "../mixins/ApplicationContextMixin"; +import { materialContextMixin } from "../mixins/MaterialContextMixin"; + const defaultPoint = "Г"; const defaultSteps = 10; -export class PointsPathFormDataProvider extends mix(JSONSchemaFormDataProvider).with( - ApplicationContextMixin, - MaterialContextMixin, -) { - static Material = Made.Material; - - static Application = Application; - +export class PointsPathFormDataProvider extends JSONSchemaFormDataProvider { constructor(config) { super(config); + this.initMaterialContextMixin(); + this.initApplicationContextMixin(); this.reciprocalLattice = new Made.ReciprocalLattice(this.material.lattice); this.symmetryPoints = this.symmetryPointsFromMaterial; } @@ -168,3 +160,6 @@ export class ExplicitPointsPath2PIBAFormDataProvider extends ExplicitPointsPathF return true; } } + +materialContextMixin(PointsPathFormDataProvider.prototype); +applicationContextMixin(PointsPathFormDataProvider.prototype); diff --git a/src/context/providers/by_application/ExecutableContextProvider.js b/src/context/providers/by_application/ExecutableContextProvider.js new file mode 100644 index 0000000..46d94ea --- /dev/null +++ b/src/context/providers/by_application/ExecutableContextProvider.js @@ -0,0 +1,10 @@ +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; + +export default class ExecutableContextProvider extends ContextProvider { + constructor(config) { + super({ + ...config, + domain: "executable", + }); + } +} diff --git a/src/context/providers/by_application/espresso/QENEBContextProvider.js b/src/context/providers/by_application/espresso/QENEBContextProvider.js new file mode 100644 index 0000000..b2d1ad3 --- /dev/null +++ b/src/context/providers/by_application/espresso/QENEBContextProvider.js @@ -0,0 +1,56 @@ +import lodash from "lodash"; + +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { materialsSetContextMixin } from "../../../mixins/MaterialsSetContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; +import QEPWXContextProvider from "./QEPWXContextProvider"; + +export default class QENEBContextProvider extends ExecutableContextProvider { + _material = undefined; + + _materials = []; + + _materialsSet = undefined; + + constructor(config) { + super(config); + this.initJobContextMixin(); + this.initMaterialsContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initMaterialContextMixin(); + this.initMaterialsSetContextMixin(); + } + + getData() { + const sortedMaterials = this.sortMaterialsByIndexInSet(this.materials); + const PWXContexts = sortedMaterials.map((material) => { + const context = { ...this.config.context, material }; + const config = { ...this.config, context }; + return new QEPWXContextProvider(config).getData(); + }); + + return { + ...lodash.omit(PWXContexts[0], [ + "ATOMIC_POSITIONS", + "ATOMIC_POSITIONS_WITHOUT_CONSTRAINTS", + ]), + FIRST_IMAGE: PWXContexts[0].ATOMIC_POSITIONS, + LAST_IMAGE: PWXContexts[PWXContexts.length - 1].ATOMIC_POSITIONS, + INTERMEDIATE_IMAGES: PWXContexts.slice(1, PWXContexts.length - 1).map( + (data) => data.ATOMIC_POSITIONS, + ), + }; + } +} + +materialContextMixin(QENEBContextProvider.prototype); +materialsContextMixin(QENEBContextProvider.prototype); +methodDataContextMixin(QENEBContextProvider.prototype); +workflowContextMixin(QENEBContextProvider.prototype); +jobContextMixin(QENEBContextProvider.prototype); +materialsSetContextMixin(QENEBContextProvider.prototype); diff --git a/src/context/providers/by_application/espresso/QEPWXContextProvider.js b/src/context/providers/by_application/espresso/QEPWXContextProvider.js new file mode 100644 index 0000000..a4ff9af --- /dev/null +++ b/src/context/providers/by_application/espresso/QEPWXContextProvider.js @@ -0,0 +1,166 @@ +import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; +import path from "path"; +import s from "underscore.string"; + +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; + +export default class QEPWXContextProvider extends ExecutableContextProvider { + _material = undefined; + + _materials = []; + + constructor(config) { + super(config); + this.initMaterialsContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initJobContextMixin(); + this.initMaterialContextMixin(); + } + + static atomSymbols(material) { + return material.Basis.uniqueElements; + } + + static uniqueElementsWithLabels(material) { + // return unique items + return [...new Set(material.Basis.elementsWithLabelsArray)]; + } + + /** Returns the input text block for atomic positions WITH constraints. + */ + static atomicPositionsWithConstraints(material) { + return material.Basis.getAtomicPositionsWithConstraintsAsStrings().join("\n"); + } + + /** Returns the input text block for atomic positions + * Note: does NOT include constraints + */ + static atomicPositions(material) { + return material.Basis.atomicPositions.join("\n"); + } + + static NAT(material) { + return material.Basis.atomicPositions.length; + } + + static NTYP(material) { + return material.Basis.uniqueElements.length; + } + + static NTYP_WITH_LABELS(material) { + return this.uniqueElementsWithLabels(material).length; + } + + buildQEPWXContext(material) { + const IBRAV = 0; // use CELL_PARAMETERS to define Bravais lattice + + return { + IBRAV, + RESTART_MODE: this.RESTART_MODE, + ATOMIC_SPECIES: this.ATOMIC_SPECIES(material), + ATOMIC_SPECIES_WITH_LABELS: this.ATOMIC_SPECIES_WITH_LABELS(material), + NAT: QEPWXContextProvider.NAT(material), + NTYP: QEPWXContextProvider.NTYP(material), + NTYP_WITH_LABELS: QEPWXContextProvider.NTYP_WITH_LABELS(material), + ATOMIC_POSITIONS: QEPWXContextProvider.atomicPositionsWithConstraints(material), + ATOMIC_POSITIONS_WITHOUT_CONSTRAINTS: QEPWXContextProvider.atomicPositions(material), + CELL_PARAMETERS: QEPWXContextProvider.CELL_PARAMETERS(material), + }; + } + + getDataPerMaterial() { + if (!this.materials || this.materials.length <= 1) return {}; + return { perMaterial: this.materials.map((material) => this.buildQEPWXContext(material)) }; + } + + /* + * @NOTE: Overriding getData makes this provider "stateless", ie. delivering data from scratch each time and not + * considering the content of `this.data`, and `this.isEdited` field(s). + */ + getData() { + // the below values are read from PlanewaveDataManager instead + // ECUTWFC = 40; + // ECUTRHO = 200; + + return { + ...this.buildQEPWXContext(this.material), + ...this.getDataPerMaterial(), + }; + } + + get RESTART_MODE() { + return this.job.parentJob || this.workflow.hasRelaxation ? "restart" : "from_scratch"; + } + + getPseudoBySymbol(symbol) { + return (this.methodData.pseudo || []).find((p) => p.element === symbol); + } + + /** Builds ATOMIC SPECIES block of pw.x input in the format + * X Mass_X PseudoPot_X + * where X is the atom label + * Mass_X is the mass of element X [amu] + * PseudoPot_X is the pseudopotential filename associated with element X + * + * Note: assumes this.methodData is defined + */ + ATOMIC_SPECIES(material) { + return QEPWXContextProvider.atomSymbols(material) + .map((symbol) => { + const pseudo = this.getPseudoBySymbol(symbol); + return QEPWXContextProvider.symbolToAtomicSpecie(symbol, pseudo); + }) + .join("\n"); + } + + ATOMIC_SPECIES_WITH_LABELS(material) { + return QEPWXContextProvider.uniqueElementsWithLabels(material) + .map((symbol) => { + const symbolWithoutLabel = symbol.replace(/\d$/, ""); + const label = symbol.match(/\d$/g) ? symbol.match(/\d$/g)?.[0] : ""; + const pseudo = this.getPseudoBySymbol(symbolWithoutLabel); + return QEPWXContextProvider.elementAndPseudoToAtomicSpecieWithLabels( + symbolWithoutLabel, + pseudo, + label, + ); + }) + .join("\n"); + } + + static CELL_PARAMETERS(material) { + return material.Lattice.vectorArrays + .map((x) => { + return x + .map((y) => { + return s.sprintf("%14.9f", y).trim(); + }) + .join(" "); + }) + .join("\n"); + } + + static symbolToAtomicSpecie(symbol, pseudo) { + const el = PERIODIC_TABLE[symbol]; + const filename = pseudo?.filename || path.basename(pseudo?.path || ""); + return s.sprintf("%s %f %s", symbol, el.atomic_mass, filename) || ""; + } + + static elementAndPseudoToAtomicSpecieWithLabels(symbol, pseudo, label = "") { + const el = PERIODIC_TABLE[symbol]; + const filename = pseudo?.filename || path.basename(pseudo?.path || ""); + return s.sprintf("%s%s %f %s", symbol, label, el.atomic_mass, filename) || ""; + } +} + +materialContextMixin(QEPWXContextProvider.prototype); +materialsContextMixin(QEPWXContextProvider.prototype); +methodDataContextMixin(QEPWXContextProvider.prototype); +workflowContextMixin(QEPWXContextProvider.prototype); +jobContextMixin(QEPWXContextProvider.prototype); diff --git a/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js new file mode 100644 index 0000000..7ab5802 --- /dev/null +++ b/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js @@ -0,0 +1,86 @@ +import { PERIODIC_TABLE } from "@exabyte-io/periodic-table.js"; +import lodash from "lodash"; +import _ from "underscore"; +import s from "underscore.string"; + +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; + +export default class NWChemTotalEnergyContextProvider extends ExecutableContextProvider { + _material = undefined; + + constructor(config) { + super(config); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initJobContextMixin(); + this.initMaterialContextMixin(); + } + + get atomicPositionsWithoutConstraints() { + return this.material.Basis.atomicPositions; + } + + get atomicPositions() { + const basis = this.material.Basis; + basis.toCartesian(); + return basis.getAtomicPositionsWithConstraintsAsStrings(); + } + + get atomSymbols() { + return this.material.Basis.uniqueElements; + } + + get cartesianAtomicPositions() { + return this.material.Basis.toCartesian !== undefined; + } + + get ATOMIC_SPECIES() { + return _.map(this.atomSymbols, (symbol) => { + return NWChemTotalEnergyContextProvider.symbolToAtomicSpecies(symbol); + }).join("\n"); + } + + /* + * @NOTE: Overriding getData makes this provider "stateless", ie. delivering data from scratch each time and not + * considering the content of `this.data`, and `this.isEdited` field(s). + */ + getData() { + /* + TODO: Create ability for user to define CHARGE, MULT, BASIS and FUNCTIONAL parameters. + */ + const CHARGE = 0; + const MULT = 1; + const BASIS = "6-31G"; + const FUNCTIONAL = "B3LYP"; + + return { + CHARGE, + MULT, + BASIS, + NAT: this.atomicPositions.length, + NTYP: this.atomSymbols.length, + ATOMIC_POSITIONS: this.atomicPositions.join("\n"), + ATOMIC_POSITIONS_WITHOUT_CONSTRAINTS: this.atomicPositionsWithoutConstraints.join("\n"), + ATOMIC_SPECIES: this.ATOMIC_SPECIES, + FUNCTIONAL, + CARTESIAN: this.cartesianAtomicPositions, + }; + } + + static symbolToAtomicSpecies(symbol, pseudo) { + const el = PERIODIC_TABLE[symbol]; + const filename = pseudo + ? lodash.get(pseudo, "filename", s.strRightBack(pseudo.path || "", "/")) + : ""; + return el ? s.sprintf("%s %f %s", symbol, el.atomic_mass, filename) : undefined; + } +} + +materialContextMixin(NWChemTotalEnergyContextProvider.prototype); +methodDataContextMixin(NWChemTotalEnergyContextProvider.prototype); +workflowContextMixin(NWChemTotalEnergyContextProvider.prototype); +jobContextMixin(NWChemTotalEnergyContextProvider.prototype); diff --git a/src/context/providers/by_application/vasp/VASPContextProvider.js b/src/context/providers/by_application/vasp/VASPContextProvider.js new file mode 100644 index 0000000..17e30c6 --- /dev/null +++ b/src/context/providers/by_application/vasp/VASPContextProvider.js @@ -0,0 +1,56 @@ +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; + +export default class VASPContextProvider extends ExecutableContextProvider { + _material = undefined; + + _materials = []; + + constructor(config) { + super(config); + this.initJobContextMixin(); + this.initMaterialsContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initMaterialContextMixin(); + } + + // eslint-disable-next-line class-methods-use-this + buildVASPContext(material) { + return { + // TODO: figure out whether we need two separate POSCARS, maybe one is enough + POSCAR: material.getAsPOSCAR(true, true), + POSCAR_WITH_CONSTRAINTS: material.getAsPOSCAR(true), + }; + } + + getDataPerMaterial() { + if (!this.materials || this.materials.length <= 1) return {}; + return { perMaterial: this.materials.map((material) => this.buildVASPContext(material)) }; + } + + /* + * @NOTE: Overriding getData makes this provider "stateless", ie. delivering data from scratch each time and not + * considering the content of `this.data`, and `this.isEdited` field(s). + */ + getData() { + // consider adjusting so that below values are read from PlanewaveDataManager + // ECUTWFC; + // ECUTRHO; + + return { + ...this.buildVASPContext(this.material), + ...this.getDataPerMaterial(), + }; + } +} + +materialContextMixin(VASPContextProvider.prototype); +materialsContextMixin(VASPContextProvider.prototype); +methodDataContextMixin(VASPContextProvider.prototype); +workflowContextMixin(VASPContextProvider.prototype); +jobContextMixin(VASPContextProvider.prototype); diff --git a/src/context/providers/by_application/vasp/VASPNEBContextProvider.js b/src/context/providers/by_application/vasp/VASPNEBContextProvider.js new file mode 100644 index 0000000..28f0125 --- /dev/null +++ b/src/context/providers/by_application/vasp/VASPNEBContextProvider.js @@ -0,0 +1,46 @@ +import { jobContextMixin } from "../../../mixins/JobContextMixin"; +import { materialContextMixin } from "../../../mixins/MaterialContextMixin"; +import { materialsContextMixin } from "../../../mixins/MaterialsContextMixin"; +import { materialsSetContextMixin } from "../../../mixins/MaterialsSetContextMixin"; +import { methodDataContextMixin } from "../../../mixins/MethodDataContextMixin"; +import { workflowContextMixin } from "../../../mixins/WorkflowContextMixin"; +import ExecutableContextProvider from "../ExecutableContextProvider"; +import VASPContextProvider from "./VASPContextProvider"; + +export default class VASPNEBContextProvider extends ExecutableContextProvider { + _materials = []; + + constructor(config) { + super(config); + this.initMaterialContextMixin(); + this.initMaterialsContextMixin(); + this.initMaterialsSetContextMixin(); + this.initMethodDataContextMixin(); + this.initWorkflowContextMixin(); + this.initJobContextMixin(); + } + + getData() { + const sortedMaterials = this.sortMaterialsByIndexInSet(this.materials); + const VASPContexts = sortedMaterials.map((material) => { + const context = { ...this.config.context, material }; + const config = { ...this.config, context }; + return new VASPContextProvider(config).getData(); + }); + + return { + FIRST_IMAGE: VASPContexts[0].POSCAR_WITH_CONSTRAINTS, + LAST_IMAGE: VASPContexts[VASPContexts.length - 1].POSCAR_WITH_CONSTRAINTS, + INTERMEDIATE_IMAGES: VASPContexts.slice(1, VASPContexts.length - 1).map( + (data) => data.POSCAR_WITH_CONSTRAINTS, + ), + }; + } +} + +materialContextMixin(VASPNEBContextProvider.prototype); +materialsContextMixin(VASPNEBContextProvider.prototype); +materialsSetContextMixin(VASPNEBContextProvider.prototype); +methodDataContextMixin(VASPNEBContextProvider.prototype); +workflowContextMixin(VASPNEBContextProvider.prototype); +jobContextMixin(VASPNEBContextProvider.prototype); diff --git a/src/context/providers/settings.js b/src/context/providers/settings.js new file mode 100644 index 0000000..39f604b --- /dev/null +++ b/src/context/providers/settings.js @@ -0,0 +1,38 @@ +import { Application } from "@exabyte-io/ade.js"; +import { Made } from "@mat3ra/made"; + +class GlobalSettings { + "PointsGridFormDataProvider.defaultKPPRA" = 5; + + Material = Made.Material; + + Application = Application; + + constructor() { + this.resetDefaults(); + } + + get defaultKPPRA() { + return this["PointsGridFormDataProvider.defaultKPPRA"]; + } + + setApplication(application) { + this.Application = application; + } + + setMaterial(material) { + this.Material = material; + } + + setDefaultKPPRA(kppra) { + this["PointsGridFormDataProvider.defaultKPPRA"] = kppra; + } + + resetDefaults() { + this.Material = Made.Material; + this.Application = Application; + this["PointsGridFormDataProvider.defaultKPPRA"] = 5; + } +} + +export const globalSettings = new GlobalSettings(); diff --git a/src/context/registry.js b/src/context/registry.js deleted file mode 100644 index 1b1d6fd..0000000 --- a/src/context/registry.js +++ /dev/null @@ -1,6 +0,0 @@ -import { ContextProviderRegistry as clsInstance } from "@exabyte-io/ade.js"; -import { extendAndPatchRegistry } from "@mat3ra/code/dist/js/context"; - -import { wodeProviders } from "./providers"; - -export const ContextProviderRegistry = extendAndPatchRegistry(clsInstance, wodeProviders); diff --git a/src/index.js b/src/index.js index e915a80..479cd54 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,3 @@ -import { ContextProviderRegistry } from "./context/registry"; import { UNIT_STATUSES, UNIT_TYPES } from "./enums"; import { createSubworkflowByName, Subworkflow } from "./subworkflows"; import { builders } from "./units/builders"; @@ -12,7 +11,6 @@ export { createSubworkflowByName, UnitFactory, builders, - ContextProviderRegistry, UNIT_TYPES, UNIT_STATUSES, }; diff --git a/src/patch.js b/src/patch.js index 05a4e59..1ce9630 100644 --- a/src/patch.js +++ b/src/patch.js @@ -1,11 +1,12 @@ import { Template } from "@exabyte-io/ade.js"; -import { ContextProviderRegistry } from "./context/registry"; +import { wodeProviders } from "./context/providers"; // We patch the static providerRegistry here so that // Template has all context providers available // to it when creating workflows. It is then re-exported // from WoDe for use downstream. -Template.providerRegistry = ContextProviderRegistry; + +Template.setContextProvidersConfig(wodeProviders); export { Template }; diff --git a/tests/context.test.js b/tests/context.test.js new file mode 100644 index 0000000..84a615c --- /dev/null +++ b/tests/context.test.js @@ -0,0 +1,69 @@ +/* eslint-disable max-classes-per-file */ +import ContextProvider from "@exabyte-io/ade.js/dist/js/context/ContextProvider"; +import { expect } from "chai"; + +import { applicationContextMixin } from "../src/context/mixins/ApplicationContextMixin"; +import { materialContextMixin } from "../src/context/mixins/MaterialContextMixin"; +import { globalSettings } from "../src/context/providers/settings"; + +class MockMaterial { + static createDefault() { + return "defaultMockMaterial"; + } +} + +class SpecificMockMaterial { + static createDefault() { + return "defaultSpecificMockMaterial"; + } +} + +class MockApplication { + static createDefault() { + return "defaultMockApplication"; + } +} + +class SpecificMockApplication { + static createDefault() { + return "defaultSpecificMockApplication"; + } +} + +class ProviderEntity extends ContextProvider { + constructor(config) { + super(config); + this.initApplicationContextMixin(); + this.initMaterialContextMixin(); + } +} + +applicationContextMixin(ProviderEntity.prototype); +materialContextMixin(ProviderEntity.prototype); + +class DerivedProviderEntity extends ProviderEntity {} + +describe("Material & Application ContextMixin", () => { + const config = { name: "test" }; + + after(() => { + globalSettings.resetDefaults(); + }); + + it("uses static entity class", () => { + globalSettings.setMaterial(MockMaterial); + globalSettings.setApplication(MockApplication); + + const provider = new ProviderEntity(config); + expect(provider.material).to.be.equal("defaultMockMaterial"); + expect(provider.application).to.be.equal("defaultMockApplication"); + }); + + it("uses static entity class from derived class", () => { + globalSettings.setMaterial(SpecificMockMaterial); + globalSettings.setApplication(SpecificMockApplication); + const provider = new DerivedProviderEntity(config); + expect(provider.material).to.be.equal("defaultSpecificMockMaterial"); + expect(provider.application).to.be.equal("defaultSpecificMockApplication"); + }); +}); diff --git a/tests/espresso.test.js b/tests/espresso.test.js new file mode 100644 index 0000000..4e33a80 --- /dev/null +++ b/tests/espresso.test.js @@ -0,0 +1,21 @@ +import { Constraint } from "@mat3ra/made/dist/js/constraints/constraints"; +import { Material } from "@mat3ra/made/dist/js/material"; +import { expect } from "chai"; + +import QEPWXContextProvider from "../src/context/providers/by_application/espresso/QEPWXContextProvider"; + +describe("QEPWXContextProvider.atomicPositionsWithConstraints", () => { + const expectedOutput = `Si 0.000000000 0.000000000 0.000000000 1 0 1 +Si 0.250000000 0.250000000 0.250000000 0 0 0`; + + it("returns each atom on its own line when input is array", () => { + const material = Material.createDefault(); + const constraints = [ + new Constraint({ id: 0, value: [true, false, true] }), + new Constraint({ id: 1, value: [false, false, false] }), + ]; + material.setBasisConstraints(constraints); + const result = QEPWXContextProvider.atomicPositionsWithConstraints(material); + expect(result).to.equal(expectedOutput); + }); +});